In this article we are going to learn how to change an ASP.Net Datagrid row and cell attributes at runtime. We are going to use C# code and make changes based on the value of the data returned from a database query. To start with let’s assume we create a Datagrid in our web form, and it looks something like this
<asp:BoundColumn HeaderText="Product ID" DataField="ProductID">
<ITEMSTYLE HORIZONTALALIGN="Left"></ITEMSTYLE>
</asp:BoundColumn>
<asp:BoundColumn HeaderText="Product Name" DataField="ProductName">
<ITEMSTYLE HORIZONTALALIGN="Left"></ITEMSTYLE>
</asp:BoundColumn>
<asp:BoundColumn HeaderText="Category " DataField="CategoryName">
<ITEMSTYLE HORIZONTALALIGN="Right"></ITEMSTYLE>
</asp:BoundColumn>
<asp:BoundColumn HeaderText="Sub Category" DataField="SubCategoryName">
<ITEMSTYLE HORIZONTALALIGN="Right"></ITEMSTYLE>
</asp:BoundColumn>
<asp:ButtonColumn HeaderText="Sales Count"
CommandName="CountOnClick" DataTextField="NoOfSales">
<ITEMSTYLE HORIZONTALALIGN="Right"></ITEMSTYLE>
For the purpose of this article I have a stored procedure ‘DataGridSample’ which retrieves some product related information from the AdventureWorks2000 database, then binds it to the datagrid. The resultant page with the datagrid looks like this:
What we want to do is highlight or change some of these attributes based on the values returned? In this article we are going to do the following:
1. Change the background color and font color of all rows where the Sales Amount is > 100,000.
2. Change the font color and font type of the Sales Count cell if its value is < 10
3. Provide a mouse over for the Product Name field
4. Disable the ability to click on Sales Count when its value is 0
5. Display ‘No Sales’ in the Sales Amount column where it is blank
6. Change the formatting of the Sales Amount field based on whether the cell has a numeric value or a string value (‘No Sales’)
ItemDataBound
The ItemDatabound event is a perfect place to makes last minute changes to the Datagrid. This event is raised after an item is bound to the Datagrid control but before it displays. This makes the event a perfect place to apply conditional logic to change the style or formatting of an item based on the item’s values. To understand the ItemDataBound event within the context of a Datagrid – this event fires each time a row (item) is bound to the grid. The first thing we need to do is create an event handler for ItemDataBound.
this.DataGrid1.ItemDataBound +=
new System.Web.UI.WebControls.DataGridItemEventHandler(DataGrid_ItemDataBound);
All I am doing here is specifying that each time a row is bound to the grid (DataGrid1), the DataGrid_ItemDataBound method must be invoked. Let’s take a look at what this method looks like:
protected void DataGrid_ItemDataBound(object sender, DataGridItemEventArgs e){ }
The first parameter passed to this event handler, is an object type, in this case the object is datagrid. The second parameter is a DataGridItemEventArgs type. This parameter encapsulates information about each item (row) after the data is bound to the datagrid. We have seen that the ItemDataBound event fires for each row in the Datagrid.
For the purpose of this example we are interested not in the header and footer rows but just the Item Rows. The first thing we need to check in our event handler is the type of row this event has fired for
if(e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
By verifying that the ItemType is either Item or Alternating item we have eliminated applying the subsequent procedural logic to all but the data rows.
Change background and font color of a datagrid row
if (Convert.ToDouble(e.Item.Cells[5].Text) > Convert.ToDouble(100000)) { e.Item.BackColor = System.Drawing.Color.LightBlue; e.Item.ForeColor = System.Drawing.Color.SandyBrown; }
Changing the font color and size of a datagrid cell
if ( Convert.ToInt32(((LinkButton)(e.Item.Cells[4].Controls[0])).Text) < 10) { e.Item.Cells[4].ForeColor = System.Drawing.Color.Red; e.Item.Cells[4].Font.Bold = true; }
A mouseover for a datagrid cell without JavaScript
In web applications, real estate (the available area on screen to display information) is often at a premium. In this little example we want to display the Product Model Name as well, but have no space in which to display it. One solution might be to display it as a mouse over event when the cursor hovers over the Product Name. There is a Tooltip class (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwindowsformstooltipclasstopic.asp) available to us which will display a small pop-up window when the mouse hovers over a control. Our first step is to add the Product Model Name column to our grid, and since we don’t want it displayed as a column, set its visibility to false.
<asp:BoundColumn Visible="False" DataField='ProductModelName"'></asp:BoundColumn>
We then set the ToolTip property of Cells[1] (Product Name) to the contents of Cells[6] (Product Model Name)
e.Item.Cells[1].ToolTip = e.Item.Cells[0].Text;
Now when your mouse hovers over the Product Name cell, the Product Model Name will appear over it.
Disable the ability to click on a datagrid ButtonColumn based on its value
Datagrid objects often use button columns, which when you click on will navigate to a more detailed version of the data. In this example we have a Sales count column which returns the number of Sales which meet a certain criteria. There are some rows which return 0 – and so there is no detail information to navigate to. In this case we want to suppress a user’s ability to click on this column.
WebControl wcTemp = ((WebControl)e.Item.Cells[4].Controls[0]); wcTemp.Enabled=false;
An alternate solution could be:
Control c = e.Item.Cells[4].Controls[0]; e.Item.Cells[4].Controls.Remove(c); e.Item.Cells[4].Text="0";
Change the displayed value of a datagrid cell at runtime
In an attempt to add to the readability factor in my Datagrid, if no value returned for the Sales Amount column, I want to change it to ‘No Sales’. Not a problem. We just need to check for a blank column and change it to the text we want displayed by using the .Text property of the datagrid item cell in question
If (e.Item.Cells[5].Text = “ ”) { e.Item.Cells[5].Text = “No Sales” }
Format a datagrid column based on its contents
While building the grid in our aspx page, we did not specify the display format for the Sales Amount column. The reason for this was, the stored procedure returns either a numeric amount field or a null value. When it returned a null value we were going to change it to a string as demonstrated in the last example. It then becomes necessary to set the display format at run time based on the value of the Sales Amount column for each row. Fortunately for us, this is quite simple.
if (e.Item.Cells[5].Text == “nbsp;”) { e.Item.Cells[5].Text = String.Format("{0}", "No Sales"); } else { e.Item.Cells[5].Text = String.Format("{0:c}", Convert.ToDouble(e.Item.Cells[5].Text)); }
Let’s compile and run our example and look at what we get.
Conclusion
The above datagrid is certainly not the prettiest ASP.Net datagrid there is, but the idea was to demonstrate how properties of datagrid cells can be changed at run time based on their values. The examples listed in this sample is not a comprehensive list of all the attributes that can be changed, rather then a collection of what seem to be the most frequently asked for.
Login to download Sample code. To experiment with these files, create a new web project in Visual Studio. Right click on the project in the Solution Explorer window and select “Add Existing Item”. Browse to the ChangeDatagrid.aspx file to import the form into the project. The stored procedure DatagridSample which is used is included too
by Llama Lopon