Posts
203
Comments
1116
Trackbacks
51
March 2006 Entries
GridView - Set column properties at run-time

An interesting issue came up today that, although it now looks simple, did not have an immediately obvious solution.  Specifically, what if you want to set properties of individual columns of a GridView at run-time (via C# code) rather than at design time in the aspx code.

For example, let's say you want to set the DataFormatString property of a BoundField column.  In short, it is a 2-part solution.  First, you must positionally extract your column out of the GridView's Columns property while casting it to your desired type (in this case a BoundField).  Second, after you have set the properties, do the databind.  So if you have column that you want to format as currency, the code might look like this:

BoundField priceField = grid.Columns[0] as BoundField;
priceField.DataFormatString =
"{0:c}";
priceField.HtmlEncode =
false;
grid.DataSource = list;
grid.DataBind();

Note that since you're manually doing the data binding this will preclude you from using the ObjectDataSource in this case (since that happens before your user code in the Page_Load event).

Taking this one step further, you could even add columns dynamically at run-time doing this:

BoundField someField = new BoundField();
someField.DataField =
"Price";
someField.DataFormatString =
"{0:c}";
someField.HtmlEncode =
false;
grid.Columns.Add(someField);

Note: One reason this might throw you off at first is that in the C# intellisense, BoundColumn comes up first and if you're not watching carefully you might try to use that instead of BoundField which will prevent you from compiling!

Posted On Thursday, March 30, 2006 6:51 PM | Comments (31)
Real world example of C# Anonymous Methods

Often when a new language features come out (in this case anonymous method) we often see syntax examples like this:

delegate void SomeDelegate();
public void InvokeMethod()
{
  SomeDelegate del = delegate()
      {
       MessageBox.Show("Hello");
      };
  del
();  
}

and we say, great but when is code like THAT ever going to be useful to me?  In that trivial example, of course that's not very useful.  But when you consider the power anonymous methods gives you both to pass in parameters and also make use of local objects then tons of possibilities are opened up for making code more concise and efficient.  Consider a case where you're using a DataReader to read multiple result sets.  Your code might look something like this:

public Person GetPerson(int personID)
{
 //(Perform data access code here to create DataReader)
 Person person = new Person();
 
 if (dr.Read())
 {
  person = personMapper.BuildItem(dr);
 }
 
 dr.NextResult();
 if (dr.Read())
 {
  person.Address = addressMapper.BuildItem(dr);
 }
 
 dr.NextResult();
 if (dr.Read())
 {
  person.EmploymentInfo = employmentMapper.BuildItem(dr);
 }
}

This code is now littered with IF statements and dr.NextResult() method calls.  To make this more concise, you could create a simple method that passes in a delegate that you can use anonymously:

public static void ReadNextResult(NullableDataReader dr, Execute execute)
{
 dr.NextResult();
 if (dr.Read())
 {
  execute();
 }
}

Then the consuming code can simply look like this:

public Person GetPerson(int personID)
{
 //(Perform data access code here to create DataReader)
 Person person = new Person();
 
 DataUtil.ReadNextResult(dr, delegate()
  { person = personMapper.BuildItem(dr); });

 DataUtil.ReadNextResult(dr, delegate()
  { person.Address = addressMapper.BuildItem(dr); });

 DataUtil.ReadNextResult(dr, delegate()
  { person.EmploymentInfo = employmentMapper.BuildItem(dr); });  
}

Notice that because of the use of anonymous methods, not only can we pass in the DataReader to the method but also we can use local objects (e.g., the “mapper” objects) inside the anonymous methods.  Internally the C# compiler creates private nested classes containing the delegates we want to execute that have member variables that are assigned the “local object” references which is why it's possible to pull this off in-line rather than having to create a completely separate method.

Posted On Tuesday, March 21, 2006 8:51 AM | Comments (6)

View Steve Michelotti's profile on LinkedIn

profile for Steve Michelotti at Stack Overflow, Q&A for professional and enthusiast programmers




Google My Blog

Tag Cloud