by Admin
7. July 2009 14:46
Download Sample Project
This was a question was asked by one of my site visitors, Mike. Following is the text of the question:
This is a similar question to one you have already answered in formatting Grid Views. However there are 2 main differences.
First: I want to change the value of a column (not the format) in any row if the row preceding it has a certain value in the same column.
This question translates to How do you change value of a data grid column based on values of previous row(s). I
generalized this question to cover all previous rows and not just the proceeding row. Answer to all such questions relies on
handling events like RowDataBound or RowCreated events. When a data grid or grid view renders,
RowDataBound fires when row is being data bound and then RowCreated is fired after it has been
data bound and row has been created. So depending on at what stage of rendering you want to change behavior of a row,
you will subscribe either of these events. In the sample project, I am subscribing to RowDataBound event.
Next step is to access values from previous rows. Here you have choice. One, you can keep some local vaiable that stores values
from previous row(s) and then use them in current row event handling. Two, you can access the previous GridRow
based on index. In this sample i will discuss the approach of accessing previous row based on index and then extracting values
from certain cells.
In RowDataBound event handler, GridViewRowEventArgs provides you access to DataItem
associated with current row only. You do not have access to DataItem associated with previous rows. But at
this point, previous rows have been prepared for rendering. You have access to all the cell values associated with previous row.
You can access GridRow object of previous rows and extract text from cells that you are interested in. In the
sample project, I am accessing ListPrice from fourth column and then displaying it in current row along with price
associated with current row. Well, this does not sound like something that is very interesting or useful. But it serves the
purpose of demonstrating you will accomplish the task.
Here is the code snippet from sample project.
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
double price = -1.0;
double prevPrice = -1.0 ;
// Access the previous row.
if (e.Row.RowIndex != 0)
{
GridViewRow prevRow = this.productsGrid.Rows[e.Row.RowIndex - 1];
if (null != prevRow &&
prevRow.RowType == DataControlRowType.DataRow)
{
double.TryParse(prevRow.Cells[3].Text, out prevPrice);
}
}
var thisRowData = e.Row.DataItem as DataRowView;
if (!Convert.IsDBNull(thisRowData["ListPrice"]))
{
double.TryParse(thisRowData["ListPrice"].ToString(), out price);
}
var ctrl = e.Row.FindControl("prevPriceLabel") as Label;
if (null != ctrl)
{
ctrl.Text = string.Format("{0} - {1}", prevPrice, price);
}
}
}
Feel free to send me any request for any other grid view implementation you would like to be
answered or implemented.