Design Pattern Riddle #12

q. I flip through the Rolodex of objects;
You donโ€™t have to know how their made.
I give a way for each object to shine,
As they walk down the object parade.

a. Iterator

~/riddle by me

Read More »

Design Pattern Riddle #11

q. Iโ€™m in the business of procreation,
But Iโ€™m not the kind who likes to crow.
I gladly give power to those that inherit;
Iโ€™m the first to tell the object, โ€œhello!โ€

a. Factory Method

~/riddle by me

Read More »

Design Pattern Riddle #10

q. I make a group of objects seem as one;
behind the scenes I resemble a deep rooted plant.
I contain a family of parents and children,
but no where in me can you find an aunt.

a. Composite

~/riddle by me

Read More »

Design Pattern Riddle #9

q. I let you take charge of the various implementations;
I am highly abstract, but generically planned.
A superclass can localize your common behavior,
but there is plenty of room for you to command.

a. Template Method

~/riddle by me

Read More »

jQuery Flexigrid Using C# 3.0 (.NET 3.5) & LINQ

When I developed my first ASP.NET MVC application, I was a little disappointed with my options for a rich grid. I initially used the grid that is part of the MVCContrib project, but it is pretty simple and there arenโ€™t many features out of the box.

I was very pleased with the code of my MVC application, but the presentation was so 1990โ€™s. With all of this new technology I thought the presentation deserved something snappy. That is when I found Flexigrid.

As I mentioned in my last blog entry, I started to use jQuery. To my joy, Flexigrid is a jQuery plugin! Flexigrid uses jQuery to asynchronously populate the contents of the grid using either XML or JSON input.

The following is an example of what the grid looks like. It contains features to sort, page, search, move columns, resize, etcโ€ฆ

flexigridExample

The User Interface portion was pretty straightforward to put together. You just need to define your columns, the data source, and some additional parameters (such as: search terms, size, etcโ€ฆ).

<pre>
</pre><table></table>


I wanted to use this opportunity to try out some new features of .NET 3.5, so I wanted to incorporate LINQ and JSON serialization.

To do this, I needed to setup some classes that the Flexigrid will recognize once serialized. Here is what I came up with.
<div><div><pre> 1: public class FlexigridViewData</pre><pre> 2: {</pre><pre> 3: public int page;</pre><pre> 4: public int total;</pre><pre> 5: public List rows = new List();</pre><pre> 6: }</pre><pre> 7:ย  </pre><pre> 8: public class FlexigridRow</pre><pre> 9: {</pre><pre> 10: public long id;</pre><pre> 11: public List<string> cell;</pre><pre> 12: }</pre></div></div>Now is the part where the fun begins. I had already retrieved the content I needed from the Middle Tier. I use LINQ to query the generic list to obtain the correct page subset and then use a helper extension method to serialize the contents to JSON.
<div><div><pre> 1: public void Page_Load()</pre><pre> 2: {</pre><pre> 3: Response.Clear();</pre><pre> 4: Response.ContentType = "text/x-json";</pre><pre> 5: Response.Write(GetPagedContent());</pre><pre> 6: Response.Flush();</pre><pre> 7: Response.End();</pre><pre> 8: }</pre><pre> 9:ย  </pre><pre> 10: private string GetPagedContent()</pre><pre> 11: {</pre><pre> 12: var pageIndex = Convert.ToInt32(Request.Params["page"]);</pre><pre> 13: var itemsPerPage = Convert.ToInt32(Request.Params["rp"]);</pre><pre> 14: var sortName = Request.Params["sortname"];</pre><pre> 15: var sortOrder = Request.Params["sortorder"];</pre><pre> 16: var query = Request.Params["query"];</pre><pre> 17:ย  </pre><pre> 18: IEnumerable pagedContacts;</pre><pre> 19: if (string.IsNullOrEmpty(query))</pre><pre> 20: {</pre><pre> 21: pagedContacts = sortOrder.Equals("asc") ?</pre><pre> 22: Contacts.OrderBy(contact => contact.GetPropertyValue(sortName)) :</pre><pre> 23: Contacts.OrderByDescending(contact => contact.GetPropertyValue(sortName)); </pre><pre> 24: }</pre><pre> 25: else</pre><pre> 26: {</pre><pre> 27: Func<Contact, bool> whereClause = (contact => contact.GetPropertyValue<string>(sortName).Contains(query));</pre><pre> 28: pagedContacts = sortOrder.Equals("asc", StringComparison.CurrentCultureIgnoreCase) ?</pre><pre> 29: Contacts.Where(whereClause).OrderByDescending(contact => contact.GetPropertyValue(sortName)) :</pre><pre> 30: Contacts.Where(whereClause).OrderBy(contact => contact.GetPropertyValue(sortName));</pre><pre> 31: }</pre><pre> 32: int count = pagedContacts.Count();</pre><pre> 33: pagedContacts = pagedContacts.Skip((pageIndex - 1) * itemsPerPage).Take(itemsPerPage);</pre><pre> 34:ย  </pre><pre> 35: const string imageLinkFormat = @"<a href=""{0}""><img src=""{1}"" border=""0"" /></a>";</pre><pre> 36: const string imageFormat = @"<img src=""{0}"" border=""0"" />";</pre><pre> 37: var flexigrid = new FlexigridViewData {page = pageIndex, total = count};</pre><pre> 38: foreach (var contact in pagedContacts)</pre><pre> 39: {</pre><pre> 40: flexigrid.rows.Add(new FlexigridRow</pre><pre> 41: {</pre><pre> 42: id = contact.ID,</pre><pre> 43: cell = new List<string> </pre><pre> 44: { </pre><pre> 45: string.Format(imageLinkFormat, ResolveUrl("~/Contact.mvc/Detail/" + contact.ID), </pre><pre> 46: ResolveUrl("~/Images/Detail.gif")), </pre><pre> 47: contact.ID.ToString(), </pre><pre> 48: contact.FirstName, </pre><pre> 49: contact.LastName, </pre><pre> 50: contact.DateOfBirth.ToShortDateString(), </pre><pre> 51: }</pre><pre> 52: });</pre><pre> 53: }</pre><pre> 54:ย  </pre><pre> 55: return flexigrid.ToJson(); </pre><pre> 56: }</pre></div></div>Here are some helper extension methods that I used to complete the above code snippets.
<div><div><pre> 1: public static class JsonHelper</pre><pre> 2: {</pre><pre> 3: public static string ToJson(this object obj)</pre><pre> 4: {</pre><pre> 5: var serializer = new JavaScriptSerializer();</pre><pre> 6:ย  </pre><pre> 7: return serializer.Serialize( obj );</pre><pre> 8: }</pre><pre> 9:ย  </pre><pre> 10: public static string ToJson(this object obj, int recursionDepth)</pre><pre> 11: {</pre><pre> 12: var serializer = new JavaScriptSerializer();</pre><pre> 13:ย  </pre><pre> 14: serializer.RecursionLimit = recursionDepth;</pre><pre> 15:ย  </pre><pre> 16: return serializer.Serialize( obj );</pre><pre> 17: }</pre><pre> 18: }</pre></div></div><div><div><pre> 1: public static T GetPropertyValue(this object component, string propertyName)</pre><pre> 2: {</pre><pre> 3: return (T) TypeDescriptor.GetProperties(component)[propertyName].GetValue(component);</pre><pre> 4: }</pre></div></div>As a side note, I did have to dive into the JavaScript and fix two issues that I came across, but other than that it works like a charm.
I would prefer if the developer of the product had a better system of tracking bugs and maintaining a forum, but in the meantime what is setup is sufficient.

Read More »