Welcome Guest!
Create Account | Login
Locator+ Code:

Search:
FTPOnline
Channels Conferences Resources Hot Topics Partner Sites Magazines About FTP RSS 2.0 Feed

Free Trial Issue of Visual Studio Magazine

Build More Robust Databinding Apps (Continued)

One major hurdle remains. The grid view still uses string literals to specify the names of properties that it should bind to. This can cause runtime error scenarios if you attempt to use an invalid property name. For example, mistype the name of one of the properties you want to bind to:

<asp:BoundField DataField="CompanyNam" HeaderText="CompanyName"/>

This code attempts to bind this BoundField to the CompanyNam property of the Customer class, but the Customer class doesn't have a CompanyNam property. Running all the automated tests won't catch this scenario, and you get an error when you run the application.

ADVERTISEMENT

Take Control of Binding
What you need to do is eliminate the use of string literals to perform databinding (see Listing 5). You must hook up code to handle the RowDataBound event explicitly, which is fired once for each row being bound to the grid. Then, you use the DataItem property and cast it to a Customer type because you know you're binding to Customer objects. Once you have the Customer object, populate all of the controls in the row by using the Generic method, which returns a control of a specified type from the current GridRow using its control ID. Next, populate this control with the value you want from the Customer object.

This solution is not far from being the codeless approach some demos promise. However, eliminating the string literals for properties gives you the ability to refactor the customer class at will, and the code-behind reflects the changes automatically. Let's demonstrate this by renaming the CompanyName property on Customer to Company. VS 2005 now supports automatic code refactorings. Rename is one of them. Go into the code for the Customer class and place the cursor anywhere inside the CompanyName property name. Right-click on the CompanyName property. This causes the Rename dialog to pop up. Use the NewName textbox to change the CompanyName property to Company.

After you hit Continue, you'll see progress bars flash to indicate that Visual Studio is renaming any references to CompanyName to become Company. Rebuild. The build succeeds. Run your unit test. They all pass! Run the app, and it will work no problem. This is great; you now have a solution that can take advantage of Visual Studio's refactoring capabilities, support changes to the underlying database schema, and support automated execution of tests that verify that the code the UI depends on is working correctly. Let's take this one step further so that you can have your cake and eat it too. One step remains before you can take this databinding solution to its optimal conclusion. Moving to code-behind means you no longer need to utilize string literals to resolve property bindings. This gain requires a fair amount of code-behind in your Web page to implement. It also introduces a new dependency between the code-behind and the names of controls in the GridView ItemTemplates. If you now want to change the control that displays a particular piece of information, you have to change it in two places: the code-behind and the ASPX page.

Fortunately, you can bind to your data source declaratively, as well as enforce compile-time verification of bindings. Begin by changing the GridView definitions in the ASPX page to take advantage of a different databinding syntax. This snippet illustrates how to use the new binding syntax to bind the CompanyName field in the ASPX page:

<asp:TemplateField HeaderText = "CompanyName">
   <ItemTemplate><span><%# 
   ((Customer)Container.DataItem).
   CompanyName %></span></ItemTemplate>
   </asp:TemplateField>

This type of databinding syntax lets you use inline code fragments that the page outputs in place. In this fragment, you cast the Container.DataItem (the current item that you're binding to) to the correct type (Customer) and then invoke the property that you want to access to populate the span.

You can continue to modify all of the ItemTemplates so that all of the fields bind using the new syntax. Once you have completed the necessary changes to the ASPX file, you can remove all of the custom databinding code that you previously added to handle binding a customer to each row in the GridView. You don't require this code anymore, as the inline code in the ASPX file takes care of pulling values from the Customer object and outputting them to places inside of the template field. This gives you, as a page designer, more freedom in how you want to lay out your Item templates. The code-behind is no longer tightly coupled to controls within the ItemTemplate:

protected void Page_Load(object sender, EventArgs e)
   {
      if (! IsPostBack)
      {
         BindCustomersGrid();
      }
   }

   private void BindCustomersGrid()
   {
      this.customersGridView.DataSource = new 
         CustomerTask().GetAllCustomers();
      this.customersGridView.DataBind();
   }

Don't forget what led you down this path in the first place. Go into the Customer class and rename the Company property back to CompanyName. Next, switch back to the ASPX file and note that the rename has not changed the inline databinding line. How has this helped, you're wondering? You're still stuck waiting to run the app, right? Wrong. Build the application.

You get a compile error stating that the Customer class does not contain a definition for CompanyName. This rename is much better than waiting to run the app to find this error.

This means you now have a databinding solution that is resilient to change from all angles. The tests for the CustomerMapper catch any change that affects the Customer table, and you have a front end that can support declarative-style binding coupled with compile-time binding checks. Using the approach described in this article might feel significantly different to many approaches that you're familiar with, but the benefits far outweigh any initial discomfort. One of the most important questions you should ask yourself as you're building a piece of application functionality: How can I automate the testing of it to ensure that I'm getting the results that I want?

The "automagic" code-free approaches to databinding are more expensive than they initially seem. They come at the expense of the ability to change underlying objects/schemas with any degree of certainty aside from running the app, and they don't give you a way to automate the testing of the databinding functionality because all of the functionality is wrapped up in declarative constructs. The more change-tolerant approach to databinding described in this article should enable you to implement databinding applications that scale better and require much less work in the maintenance phase.

About the Author
Jean-Paul S. Boodhoo is a senior .NET delivery expert who has been working with the .NET Framework since beta 1 of .NET 1.0. He spends his days working as a senior developer for ThoughtWorks building enterprise-scale applications that utilize the .NET Framework and agile methods. Reach Jean-Paul at .

Back to top














Java Pro | Visual Studio Magazine | Windows Server System Magazine
.NET Magazine | Enterprise Architect | XML & Web Services Magazine
VSLive! | Thunder Lizard Events | Discussions | Newsletters | FTP Home