Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
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;
}
}


Posted 09-20-2006 8:41 PM by Christopher Bennage

[Advertisement]

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)