Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Christopher Bennage

Our WPF book is now available!


Custom Fields for GridView Tips

This is a followup to my post on creating a DropDownField for the GridView control. Just a couple of tips for anyone else who might be developing custom columns for the GridView.  If you don't care about customizing the GridView, don't bother reading this.

Tip #1 - Respect the Page Lifecycle

The distinction between the two methods I mentioned previously,  InitializeDataCell and OnDataBindField, was vague to me at first.  It didn't seem to matter which method I used for creating controls to insert into the GridView. Now, I'm a little wiser.  You want to instantiate your controls in InitializeDataCell so that their change events will fire, if you want and instantiate them in OnDataBindField it will be to late.  Additionally, you will not be able to access the bound data until the DataBinding event, thus the need for the second method.

Tip #2 - Beware of Adding Members to DataControlFieldCell

There is only one instance of field defined in a GridView regardless of the number of rows. When I first attempted to create a custom field, I inherited from DataControlFieldCell and added a private member of type TextBox called EditControl.  I set EditControl in InitializeDataCell to a new TextBox, and set the .Text property in OnDataBindField.  My first test only had one row of data in the GridView and everything seemed to work.  My second test had many rows of data, and it no longer worked.  I discovered that my EditControl field was being shared across every row, because there is only one instance of the each field.

The solution was to  do something like this:

        protected override void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
        {

            cell.DataBinding += OnDataBindField;

            if ((rowState & DataControlRowState.Edit) != DataControlRowState.Normal)
            {
                cell.Controls.Add(new TextBox());
            }
        }
and
protected override void OnDataBindField(object sender, EventArgs e)
{
DataControlFieldCell cell = (DataControlFieldCell) sender;

string myBoundData = GetValue(cell.NamingContainer).ToString();

if ((rowState & DataControlRowState.Edit) != DataControlRowState.Normal)
{
(cell.Controls[0] as TextBox).Text = myBoundData;
}
else
{
cell.Text = myBoundData;
}
}



About Christopher Bennage

Christopher is a software developer and consultant at Blue Spire Consulting, a company he co-founded with Rob Eisenberg in 2006. He is a Christian, a marginal musician, and an armchair philosopher. His interests include programming, liberal education, science, truth, beauty, and a number of deceased British authors (C. S. Lewis, G. K. Chesterton, and most recently Owen Barfield.) He lives in Tallahassee, FL with his wife and three children and still prefers to play as the Night Elves in WarCraft 3.
Check out Devlicio.us!

Our Sponsors

Red-Gate!