format individual cells in DataGrid by data value and column type

B

Bruce

I have a web form with a programmatically generated DataGrid. The DataGrid
columns are defined at run-time based on a SQL query. A class is derived
from ITemplate to handle a fixed set of column types. Here is a code
fragment:

namespace ApplianceBook
{
public enum DisplayType
{
Fraction = 1,
Percentage = 2,
Integer = 3,
Decimal = 4,
String = 5
}

public class CTemplateColumn : ITemplate
{
private ListItemType columnListItemType;
private string columnName;
private int columnWidth;
private DisplayType columnDisplayType;

public CTemplateColumn(string ColumnName, int ColumnWidth,
ListItemType ColumnListItemType, DisplayType ColumnDisplayType)
{
columnName = ColumnName;
columnWidth = ColumnWidth;
columnListItemType = ColumnListItemType;
columnDisplayType = ColumnDisplayType;
}

public void InstantiateIn(Control container)
{
switch (columnDisplayType)
{
case DisplayType.Fraction:
Label labelFraction = new Label();
labelFraction.ID = columnName;
labelFraction.Width = columnWidth;
if ((columnListItemType != ListItemType.Header) &&
(columnListItemType != ListItemType.Footer))
{
labelFraction.DataBinding += new
EventHandler(this.OnDataBindingFraction);
}
container.Controls.Add(labelFraction);
break;

case DisplayType.Percentage:
Label labelPercentage = new Label();
labelPercentage.ID = columnName;
labelPercentage.Width = columnWidth;
if ((columnListItemType != ListItemType.Header) &&
(columnListItemType != ListItemType.Footer))
{
labelPercentage.DataBinding += new
EventHandler(this.OnDataBindingPercentage);
}
container.Controls.Add(labelPercentage);
break;


Everything works as expected and I am able to modify the actual text in each
cell based on its ColumnDisplayType. However, I also want to be able to
format individual DataGrid cells based on ColumnDisplayType. For example, a
cell with a ColumnDisplayType with percentage data should have its cell
background color set to red if the data value is greater than 50%. Here is
my event handler for the Percentage column type:

public void OnDataBindingPercentage(object sender, EventArgs e)
{
GridViewRow container;
if (sender.GetType().ToString() == "System.Web.UI.WebControls.Label")
{
Label label = (Label)sender;
container = (GridViewRow)label.NamingContainer;
// Format data to display as a percentage value.
label.Text = String.Format("{0:0%}",
((DataRowView)container.DataItem)[columnName]);
}
}


In the above code I am able to access the data stored in the cell via
((DataRowView)container.DataItem)[columnName] but I can't find a way to
access the cell object containing the data so that I can apply cell-level
formatting. The container object doesn't seem to support accessing a
particular cell in the row using the the columnName as an index.

I want to be able to do something like the following (fictitious) code:

if (((DataRowView)container.DataItem)[columnName] > .5)
{
((DataRowView)container.DataItem).Row.Cells[columnName].BackgroundColor
= Red;
}

Unfortunately, DataRowView.Row does not have a Cells property.

How do you access the DataGrid cell associated with the current databinding
event? Any instructions or sample code for doing so would be a big help.
Thanks.
 
B

Bruce

OK, I found a way to do what I want but it sure is ugly. There's got to be a
better way than iterating through all cells to find the one with the matching
ID:

public void OnDataBindingPercentage(object sender, EventArgs e)
{
GridViewRow container;
if (sender.GetType().ToString() == "System.Web.UI.WebControls.Label")
{
Label label = (Label)sender;
container = (GridViewRow)label.NamingContainer;
// Format data to display as a percentage value.
label.Text = String.Format("{0:0%}",
((DataRowView)container.DataItem)[columnName]);
// Find index of cell with matching ID.
int CellIndex = -1;
for (int i = 0; i < container.Cells.Count; i++)
{
if (container.Cells.Controls[0].ID == columnName)
{
CellIndex = i;
break;
}
}
if (CellIndex != -1)
{ // Perform cell-level formatting.
((GridViewRow)container).Cells[CellIndex].HorizontalAlign =
HorizontalAlign.Center;
}
break;
}
}
I have a web form with a programmatically generated DataGrid. The DataGrid
columns are defined at run-time based on a SQL query. A class is derived
from ITemplate to handle a fixed set of column types. Here is a code
fragment:

namespace ApplianceBook
{
public enum DisplayType
{
Fraction = 1,
Percentage = 2,
Integer = 3,
Decimal = 4,
String = 5
}

public class CTemplateColumn : ITemplate
{
private ListItemType columnListItemType;
private string columnName;
private int columnWidth;
private DisplayType columnDisplayType;

public CTemplateColumn(string ColumnName, int ColumnWidth,
ListItemType ColumnListItemType, DisplayType ColumnDisplayType)
{
columnName = ColumnName;
columnWidth = ColumnWidth;
columnListItemType = ColumnListItemType;
columnDisplayType = ColumnDisplayType;
}

public void InstantiateIn(Control container)
{
switch (columnDisplayType)
{
case DisplayType.Fraction:
Label labelFraction = new Label();
labelFraction.ID = columnName;
labelFraction.Width = columnWidth;
if ((columnListItemType != ListItemType.Header) &&
(columnListItemType != ListItemType.Footer))
{
labelFraction.DataBinding += new
EventHandler(this.OnDataBindingFraction);
}
container.Controls.Add(labelFraction);
break;

case DisplayType.Percentage:
Label labelPercentage = new Label();
labelPercentage.ID = columnName;
labelPercentage.Width = columnWidth;
if ((columnListItemType != ListItemType.Header) &&
(columnListItemType != ListItemType.Footer))
{
labelPercentage.DataBinding += new
EventHandler(this.OnDataBindingPercentage);
}
container.Controls.Add(labelPercentage);
break;


Everything works as expected and I am able to modify the actual text in each
cell based on its ColumnDisplayType. However, I also want to be able to
format individual DataGrid cells based on ColumnDisplayType. For example, a
cell with a ColumnDisplayType with percentage data should have its cell
background color set to red if the data value is greater than 50%. Here is
my event handler for the Percentage column type:

public void OnDataBindingPercentage(object sender, EventArgs e)
{
GridViewRow container;
if (sender.GetType().ToString() == "System.Web.UI.WebControls.Label")
{
Label label = (Label)sender;
container = (GridViewRow)label.NamingContainer;
// Format data to display as a percentage value.
label.Text = String.Format("{0:0%}",
((DataRowView)container.DataItem)[columnName]);
}
}


In the above code I am able to access the data stored in the cell via
((DataRowView)container.DataItem)[columnName] but I can't find a way to
access the cell object containing the data so that I can apply cell-level
formatting. The container object doesn't seem to support accessing a
particular cell in the row using the the columnName as an index.

I want to be able to do something like the following (fictitious) code:

if (((DataRowView)container.DataItem)[columnName] > .5)
{
((DataRowView)container.DataItem).Row.Cells[columnName].BackgroundColor
= Red;
}

Unfortunately, DataRowView.Row does not have a Cells property.

How do you access the DataGrid cell associated with the current databinding
event? Any instructions or sample code for doing so would be a big help.
Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top