Reputation: 15477
I have a datatable that I bind to a gridview. The columns are variable so I'd like to take advantage of AutoGeneratedColumns. I'd like to bind an image in certain condtions. What do I need to do?
void GridView1_RowCreated(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
DataRowView drv = e.Row.DataItem as DataRowView;
if (drv != null)
drv[1] = new HtmlImage() { Src = "add.png" };
}
Upvotes: 0
Views: 2241
Reputation: 653
It sounds like the AutoGeneratedColumns property won't help you here because column types apply to the whole GridView; they are not calculated per-row.
You might be able to use a TemplateField with databinding to conditionally format the field for each row without writing any code.
If that doesn't get it done for you, I suppose you will have to write code. Bear in mind that the RowCreated event always fires (event on postback) when a row is created, but will only give you a non-null DataItem (e.Row.DataItem
) when the GridView actually goes to its DataSource for databinding; if the GridView has cached its rendered state (in ViewState), the data item will be null. At that point, you would only be able to access the row's primary key fields by doing something like this: var keys = myGridView.DataKeys[rowIndex];
(The primary key fields are determined by the value you give the GridView's DataKeyNames
property, and are stored in ViewState so that you can access them on postback.)
You would also be careful when modifying a column that is some type of DataBoundField (as most Fields are); since the RowDataBound event happens after the RowCreated event, any manual changes to the content of a row/cell you make in the RowCreated event handler are going to be clobbered by databinding when RowDataBound is fired.
That said, RowDataBound is probably the event you want.
The RowDataBound event will always give you a non-null DataItem, but only fires when real databinding happens (as opposed to "binding" from ViewState); so typically this event does not fire at all on postbacks. That's OK, though, since the GridView will remember its state for you.
If you must use code, it should probably look something like this:
//don't forget to attach this event handler, either in markup
//on the GridView control, in code (say, in the Page_Init event handler.)
protected void GridView1_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
//HtmlImage gives you a plain-vanilla <img> tag in the HTML.
//If you need to handle some server side events (such as Click)
//for the image, use a System.Web.UI.WebControls.Image control
//instead.
HtmlImage img = new HtmlImage() { Src = "path/to/image.jpg" };
e.Row.Cells[1].Controls.Add(img);
}
But, seriously, check out TemplateField first.
Upvotes: 1
Reputation: 370
This should work, it uses the controls of the actual cell:
void GridView1_RowCreated(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
HtmlImage img = new HtmlImage() { Src = "add.png" };
e.Row.Cells[1].Controls.Add(img);
}
Upvotes: 1
Reputation: 5909
You can use RowDataBound event to process each row:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView drv = e.Row.DataItem as DataRowView;
if (drv != null)
{
// your code here...
}
}
}
For more information about this event see here
Upvotes: 1