TwitterFacebookGoogle

Making ASP .NET Gridview a little less painful

Isn’t it pain in the neck when you have to write the following for every input control whose value you want to extract from a Gridview:

public static void myGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
   string firstname = ((TextBox)myGridview.Rows[e.RowIndex].
                                            FindControl("txtFirstname")).Text;
   string lastname = ((TextBox)myGridview.Rows[e.RowIndex].
                                            FindControl("txtLastname")).Text;
 
   //....and so on.. 
}

Well, you can make it a little easier by implementing the following method either in a class that extends GridView or by writing a extension method. In this example, I’ve written it as an extension method.

public static T FindControl<T>(this GridView gridView, string cntrlName, 
                                          int rowIndex)
      where T : Control
{
   return (T)(gridView.Rows[rowIndex].FindControl(cntrlName));
}

Now the code inside my page is little cleaner and easier to write:

public static void myGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
   string firstname = gridView.FindControl<TextBox>("txtFirstname", e.RowIndex).Text;
   string lastname = gridView.FindControl<TextBox>("txtLastname", e.RowIndex).Text;
 
     //....and so on.. 
}

I admit it’s not something huge but it definitely is a big help when you have to type in that statement for every single control in your Gridview!

I hope that helps some!

Twitter Email Linkedin Digg Stumbleupon Subscribe

Extension methods in C# 3.0

C# 3.0 provides a very useful feature named Extension Methods. Extension methods allow you “extend” existing classes by giving you the ability to define new methods on them. For example, I can implement my very own method, say MyStringMethod(), on the existing .NET System.String class. I would then be able to call this method like any other method in String class:

string s = "";
s.MyStringMethod();

Pretty neat, huh? But besides the syntactic sugar, there are a few additional advantages to using extension methods:

  1. Extension methods are fully supported by Visual Studio Intellisense making them easier to discover. Thus whenever someone, provided that he/she is using my library, types in ‘string.’, Intellisense will display my method as well.

  2. The other advantage is related to overall system design and usability. If you’ve been programming for a while, then you’ve probably used and/or implemented utility methods. Typically these are public static methods like:

    public static object Clone(object from, object to);
    public static cbool IsNumeric(string s);
    public static string FormatDateTime(DateTime d, int timeZoneOffset);

    Overtime the utility classes get bigger and bigger making the methods inside them more and more obscure. This can even result into the same method being implemented twice, especially so if you have multiple utility classes that aren’t very well defined. By turning these methods into extension methods we make them easier to find and thus avoid duplication.

    So how do we turn them into extension methods? By adding the keyword ‘this’ in front of the parameter to which this method ought to belong. Below is what the above method declarations look like after we turn them into extension methods:

    public static object Clone(this object from, object to);
    public static bool IsNumeric(this string s);
    public static string FormatDateTime(this DateTime d, int timeZoneOffset);

    Note that the methods must be static and must belong to a static class. I personally prefer creating separate extensions classes to house the methods. So,

    StringExtensions.cs will contain all my String extension methods,
    DateTimeExtensions.cs will contain all my DateTime extension methods…

    …and so on.

    I hope you’ve found this post to be helpful and informative. Please leave your feedback and/or comments to help me improve. Thanks!

    Twitter Email Linkedin Digg Stumbleupon Subscribe

An easier way to write HTML input forms

Consider the block of code below:

<table cellpadding="3">
  <tr>
    <td valign="top">
      <b>First Name</b>
    </td>
    <td>
      <asp:TextBox ID="txtFirstName" runat="server" />
      <div>
        Please enter your first name.</div>
    </td>
  </tr>
  <tr>
    <td valign="top">
      <b>Last name</b>
    </td>
    <td>
      <asp:TextBox ID="txtLastName" runat="server" />
      <div>
        Please enter your last name.</div>
    </td>
  </tr>
</table>

The rendered output looks something like this:
HTML Input Form
You will notice that we have to repeat the
and the tags, along with any style information that these contain, for every row of our input form. Ouch! That's a lot of typing. Furthermore, if, in the future, we have make layout and/or style related changes, we'd have to modify all the pages in our application that contain these HTML input forms! Fortunately, there is an easier way.

By implementing a couple of simple ASP .NET server controls, we will save ourselves the trouble of typing the above shown HTML and will be able to simply type the following:

<cc:Form runat="server">
  <cc:FormField runat="server" Name="First Name" 
                      Description="Please enter the first name.">
    <asp:TextBox ID="txtFirstName" runat="server" />
  </cc:FormField>
  <cc:FormField runat="server" Name="Last Name" 
                     Description="Please enter the last name.">
    <asp:TextBox ID="txtLastName" runat="server" />
  </cc:FormField>
</cc:Form>

Now isn't that soo much more pleasant to the eyes and easier on your fingers? So how is this accomplished? As follows:

First, create a ASP .NET Server Control name Form.cs. This simple control will simply render the

tags. Below is the code for it:

public class Form : WebControl
{
  public override void RenderBeginTag(HtmlTextWriter writer)
  {
    writer.Write("<table cellpadding='3'>");
  }
  public override void RenderEndTag(HtmlTextWriter writer)
  {
    writer.Write("</table>");
  }
}

Notice the use of [ParseChildren(false)] attribute. This attributes ensures that 1) we will be able to nest additional controls inside this control and 2) The nested control won't actually become a child control this control. The second point is important and will explained in greater detail shortly.

Now we move on to the more interesting control: the FormField.cs control. This control renders the

's, tag
  • The column that contains the input field label. For example:
    <td><b>First Name</b></td>
  • The opening
  • tag for the column that contains the actual input field.

  • The
    tag containing the input field description. For example:

    <div>Please enter the first name</div>
  • The closing
  • tag

    Well, that all sounds well and good. But wait! Where is the FormField control rendering the actual input field (the asp:TextBox)? The answer is that it isn’t. The use of the [ParseChildren(false)] attribute prevents the parsing of any embedded controls that FormField may have. Thus, in our example, when the Form and the FormField control's rendering has finished, the page control tree looks something like this:

    
    - Page
      - Form
      - FormField
      - LiteralControl("
    's, the input field label, and the input field description. Below is the code for it:

    [ToolboxData("<{0}:FormField runat=server></{0}:FormField>"), ParseChildren(false)]
    public class FormField : WebControl
    {
      public string Name
      {
        get { return ViewState.GetAsString("Name"); }
        set { ViewState["Name"] = value; }
      }
      public string Description
      {
        get { return ViewState.GetAsString("Description"); }
        set { ViewState["Description"] = value; }
      }
      public string NameAlign
      {
        get { return ViewState.GetAsString("NameAlign"); }
        set { ViewState["NameAlign"] = value; }
      }
      public string ControlAlign
      {
        get { return ViewState.GetAsString("ControlAlign"); }
        set { ViewState["ControlAlign"] = value; }
      }
      public override void RenderBeginTag(HtmlTextWriter writer)
      {
        string beginHtml = @"<tr><td align={0}><b>{1}</b></td><td align={2}>";
        writer.Write(string.Format(beginHtml, NameAlign, Name, ControlAlign));
      }
      public override void RenderEndTag(HtmlTextWriter writer)
      {
        string endHtml = @"<div>{0}</div></td></tr>";
        writer.Write(endHtml, Description);
      }
    }

    The interesting parts of the class are the RenderBeginTag() and the RenderEndTag() methods. If you inspect these methods, you’ll see that the RenderBeginTag() is responsible for rendering:

    • The opening
    tag for the column that contains the actual input field (like the , for example)

    And the RenderEndTag() method is responsible for rendering:

    • The closing
    ") - LiteralControl("
    ") - TextBox - LiteralControl("
    Please enter first name
    ") .....

    Notice that the TextBox (txtFirstName) is a child of the Page instead of being a child of the FormField control. What this means is that instead of having to type something convoluted like:

    string firstName = ((TextBox)this.formField1.FindControl("txtFirstName")).Text;

    your page can directly reference the TextBox like so:

    string firstName = txtFirstname.Text

    I hope you’ve found this post helpful and informative. Please take some time to leave your feedback and/or comments to help me improve.

    Twitter Email Linkedin Digg Stumbleupon Subscribe
    CyberChimps