Pages

Wednesday 6 April 2011

A pattern for binding items to a ListControl

Almost every time that I create a webform, I have to put a DropDownList or other
ListControl in order to bind a set of values. Doing this is fairly simple, just
set the properties DataSource, DataValueField and DataTextField to the appropriated
values and then perform a DataBind, but notice that this implies writing four lines
of code just to perform this particular task and when you have more ListControls
in a single webform, the amount of code for doing this binding would be overwhelming.
That is why I developed the BindHelper Pattern, which is simply a set of functions
that perform the binding task for me. For instance, if we have an entity called
CountryBrl (the suffix Brl stands for BusinessRulesLayer) and we want to have a
bindhelper for it, then the code would be like this:



Partial Public Class CountryUil



  Public Shared Sub Bind(ByVal control As ListControl, _
   ByVal objList As List(Of CountryBrl), _

   Optional
ByVal firstItem As ListItem = Nothing, _

   Optional
DataTextField As String = "Name")


   SortList
.SortByProperty(objList,_

      DataTextField, _

      SortOrder.Asc)

   control.DataSource = objList

   control.DataValueField = "ID"
   control.DataTextField = DataTextField
   control.DataBind()

   'Commonly used for a "Select" item

    If
Not firstItem Is Nothing Then

     control.Items.Insert(0, firstItem)
    End If

  End
Sub

 
  Public Shared Function BindToListControl(ByVal control As ListControl, _
    Optional ByVal firstItem As ListItem = Nothing, _

    Optional
DataTextField As String = "Name") _

    As List(Of CountryBrl)


   Dim
objList As List(Of CountryBrl)


   objList = CountryBrl.GetAll()


   Bind(control, objList, _
    firstItem:=firstItem, _
    DataTextField:=DataTextField)


    Return
objList


  End
Function


End
 Class

The code above implements:

  • A class called CountryUil (the suffix Uil stands for User Interface Layer).
  • A static core method responsible for the binding task: this method receives the
    ListControl to bind the data to, a list of entities as the data source, and optional
    parameter to show at the top of the ListControl (Commonly used for “Select”) and
    an optional parameter that specifies the field to be used as the DataTextField in
    the ListControl.
  • A static method called BindToListControl which receives the same parameters except
    for the list of entities. This method loads the data from the model, sorts the data
    by the field corresponding to the parameter DataTextField and then calls the method
    Bind.

To clarify how to use this class I proceed to show some examples:

Protected
  Sub Page_Load(ByVal sender As Object, _  
   ByVal
e As System.EventArgs)


   'ddlCountries is a DropDownList

   'chkCountries is a ChekBoxList
   
   'The default configuration: loads all
   'the countries and binds them to

   'the control showing the name and putting
   'as the first item the "Select"

   CountryUil.BindToListControl(ddlCountries, _
     New
ListItem("Select", 0))



   'Loads all the countries and binds them to

   'the control showing the CountryCode
   'and putting as the first item the "Select"

   CountryUil.BindToListControl(ddlCountries, _
    New
ListItem("Select", 0), _

    "CountryCode")

 
   'Loads all the countries and binds them to

   'the control showing the CountryCode

   CountryUil.BindToListControl(chkCountries, _
    DataTextField:="CountryCode")


   'Loads all the countries and binds them to

   'the control showing the Name

   CountryUil.BindToListControl(chkCountries)


   'performs the binding using a set of data 

   'available in the session
    CountryUil.Bind(chkCountries, Session("Countries"))



End Sub

And that’s it, we performed multiple binds by calling the same utility and this
is saving us a lot of code and time.

It is important to mention that I do not write this kind of code by hand, I use
a code generator to do it for me. The generator creates BindHelpers for every single
table in my database including the methods for binding by foreign keys like this:

CityUil.BindToListControlByCountryId(chkCities, intCountryId,...)
And since the class is generated as partial, I am able to create custom bind methods
in a separate file, very useful when working with code generators.
I hope this Code Saves Your Day as it did with mine.

No comments:

Post a Comment