I wish to add an additional class to a GridView programatically. I know I can do this using the following code:
public void RowDataBound(object sender, GridViewRowEventArgs e)
{
DataRow row = ((DataRowView)e.Row.DataItem).Row;
if (!row.Field<Boolean>("IsActive"))
{
e.Row.Attributes["class"] += "InActive";
}
}
and it works fine. The class "IsActive" is added, however, on alternating rows I end up with this HTML:
<tr class="gvAlternatingStyle" class="InActive"
onmouseover="gvMouseOver(this)"
onmouseout="gvMouseOut(this)" style="cursor:pointer;">
Two class definitions is not what I want. I would prefer to have something like this:
<tr class="gvAlternatingStyle InActive"
onmouseover="gvMouseOver(this)"
onmouseout="gvMouseOut(this)" style="cursor:pointer;">
which is, of course, more valid.
I cannot seem to figure out where/how to adjust this html. Possibly in OnPreRender() but I don't see where. Can anyone give me a pointer?
You could take care of the AlternatingRowStyle-CssClass yourself and add the extra class when needed. You will need to remove it from the GridView header of course.
string AlternatingRowStyleCssClass;
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//check if the row is a datarow
if (e.Row.RowType == DataControlRowType.DataRow)
{
string myClass = string.Empty;
//get the AlternatingRowStyle-CssClass for reference into a variable and delete from the gridview itself
if (e.Row.RowIndex == 0)
{
AlternatingRowStyleCssClass = GridView1.AlternatingRowStyle.CssClass;
GridView1.AlternatingRowStyle.CssClass = "";
}
//check if the row is alternate, if so set the alternating class
if (e.Row.RowIndex % 2 == 1)
{
myClass = AlternatingRowStyleCssClass;
}
//check if you need to add the extra class
DataRow row = ((DataRowView)e.Row.DataItem).Row;
if (!row.Field<Boolean>("IsActive"))
{
myClass += " Inactive";
}
//add all the classes to the row
e.Row.Attributes["class"] = myClass.Trim();
}
//add the class to the gridview again (maybe relevant for postback)
if (e.Row.RowType == DataControlRowType.Footer)
{
GridView1.AlternatingRowStyle.CssClass = AlternatingRowStyleCssClass;
}
}
After muddling with this a while and with help from VDWWD I worked out how to accomplish this with a combination of the above and OnPreRender():
public void RowDataBound(object sender, GridViewRowEventArgs e)
{
DataRow row = ((DataRowView)e.Row.DataItem).Row;
if (!row.Field<Boolean>("IsActive")) {
e.Row.Attributes["class"] += "InActive";
}
protected void PreRender(object sender, EventArgs e)
{
foreach(GridViewRow row in GridView1.Rows)
{
if ((row.Attributes["class"] == "InActive")&&
(row.RowState == DataControlRowState.Alternate)){
row.RowState = DataControlRowState.Normal;
row.Attributes["class"] = "gvAlternatingStyle InActive";
}
}
}
Related
I want to change the CSS styling of the first row in a gridview:
protected void hoursReportGridView_OnRowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridViewRow firstRow = hoursReportGridView.Rows[0];
firstRow.CssClass = "firstRow";
}
}
I am getting this error: Index was out of range. Must be non-negative and less than the size of the collection.
In every instance there are multiple rows returned so I don't understand the issue
'
I assume the first row exists in GridView.Rows after RowDataBound. So you can access it afterwards. So i would use DataBound instead. Note that you also set the first row on every row since RowDataBound is triggered for every row in the grid.
protected void hoursReportGridView_DataBound(object sender, EventArgs e)
{
if(this.hoursReportGridView.Rows.Count > 0)
hoursReportGridView.Rows[0].CssClass = "firstRow";
}
Another option is to use GridViewRow.RowIndex
protected void hoursReportGridView_OnRowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if(e.Row.RowIndex == 0)
e.Row.CssClass = "firstRow";
}
}
Try this:
protected void hoursReportGridView_OnRowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowIndex == 0)
{
e.Row.CssClass = "firstRow";
}
}
Why do you want to do that on the databind for every row?
Just do it in Page_Load:
// Run this after any binding calls, obviously
if(hoursReportGridView.Rows.Count > 0)
{
hoursReportGridView.Rows[0].CssClass = "firstRow";
}
protected void gridview1_RowDataBound(object sender, GridViewRowEventArgs e)
{
**if (e.Row.RowIndex >= gridview1.PageSize) // ROW FOOTER TOTAL**
{
e.Row.BackColor = System.Drawing.Color.Firebrick;
e.Row.ForeColor = System.Drawing.Color.White;
}
}
This code works sometimes, someone can help me
DM,cheers
You can try to find the last column in the PreRender event
protected void grid_PreRender(object sender, EventArgs e)
{
GridViewRow row = grdAlert.Rows[grdAlert.Rows.Count - 1];
// do stuff with your row
}
If you just need to change the style of the footer you can use
<asp:GridView ID="grid" runat="server" FooterStyle="your style"></asp:GridView>
A grid view doesn't appear to have a row count until it's finished binding each row. So, another thought:
Can you determine the number of rows from the datatable that the gridview is binding to, then store that in a variable for use later?
you can find last row like this
GridViewRow row = GridView1.Rows[GridView1.Rows.Count-1];
or use this
protected void gridview1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridView grid = (GridView)sender;
if(e.Row.RowIndex == (grid.Rows.Count - 1))
{
//last row
}
}
}
It seems that you want to detect the footer row in RowDataBound since you have commented //ROW FOOTER TOTAL, you just have to check for the DataControlRowType.Footer:
protected void gridview1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Footer)
{
// here it is
}
}
Otherwise you could compare the RowIndex with the row of the undrlying DataItem:
DataRowView row = (DataRowView)e.Row.DataItem;
if (e.Row.RowIndex == row.DataView.Count - 1) ; // last row
In your page load method set colors as below
protected void Page_Load(object sender, EventArgs e)
{
//code what you currently have ....
// add below code after that
GridViewRow row = GridView1.Rows.Count-1;
row.BackColor = System.Drawing.Color.Firebrick;
row.ForeColor = System.Drawing.Color.White;
}
I have a simple for each loop checking the text in the 10th cell of my gridview, then setting the colour of that cell to green or red dependant in the text.
This is working fine apart from the very first cell in the first row is being ignored. Ive had similar situations to this with for loops, but not a for each.
Heres my code:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
GridView vg = GridView1;
foreach (GridViewRow row in vg.Rows)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (e.Row.Cells[10].Text == "Order has been dispatched.")
{
e.Row.Cells[10].BackColor = Color.LawnGreen;
}
if (e.Row.Cells[10].Text == "Order is being processed.")
{
e.Row.Cells[10].BackColor = Color.Red;
}
}
}
}
I don't know if this will help. Probably not. But you have redundant code. Change your code to the following and make sure the event handler gets called for each row. I don't think you have to make sure the GridViewRow.RowType is a DataRow, since you will only get this event on a DataRow.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.Cells[10].Text == "Order has been dispatched.")
e.Row.Cells[10].BackColor = Color.LawnGreen;
if (e.Row.Cells[10].Text == "Order is being processed.")
e.Row.Cells[10].BackColor = Color.Red;
}
I have a gridview which checks some values on rowDataBound event.I want to remove some rows based on conditions checked in rowDataBound.I tried putting all controls in a Panel and hiding that panel ie,
TRY 1 :
protected void grdFeatured_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//some other codes here
//IMPLEMENT FILTER ACCORDING TO ABOVE 'VIS' OUTPUT
if (vis > 0)
{
Panel1.Visible = false;
}
}
}
PROBLEM :
This messes up the paging since rows are hidden but page count occurs and shows page numbers for the remaining visible rows.
TRY 2 :
protected void grdFeatured_RowDataBound(object sender, GridViewRowEventArgs e)
{
GridViewRow gvr = e.Row;
if (e.Row.RowType == DataControlRowType.DataRow)
{
//some other codes here
//IMPLEMENT FILTER ACCORDING TO ABOVE 'VIS' OUTPUT
if (vis > 0)
{
gvr.Parent.Controls.RemoveAt(gvr.RowIndex);
}
}
}
PROBLEM :
gives error :
Specified argument was out of the range of valid values.
Parameter name: index at gvr.Parent.Controls.RemoveAt(gvr.RowIndex);
dont want to edit datasource, help me out guys .
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (somecondition)
{
e.Row.Visible = false;
}
}
I need to change the colour of gridview cells based on the data value. I can quite easily do this using a datarow view in the Gridviews RowDataBound Event and an if statement (see below), however I need to do this on 30 columns which will be rather long winded and a pain to change if the business rules change. How can I encapsulate the following into a reusable method that I can call and just pass in the data column and the cell index ?
protected void gv1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.DataItem != null)
{
DataRowView drv = (DataRowView)e.Row.DataItem;
int A = Int32.Parse(drv["A"].ToString());
if (A <= 74)
{
e.Row.Cells[2].BackColor = System.Drawing.Color.Red;
}
}
}
public void SetColor(DataGridViewRow row, string columnName, int cellIndex)
{
var data = (GridViewRow)row.DataItem;
int number = Convert.ToInt32(data[columnName]);
if (number > 74) return;
row.Cells[cellIndex].BackColor = Color.Red;
}
protected void gv1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType != DataRowType.DataRow) return;
SetColor(e, "A", 2);
}
Figured it out - Mr Meckley put me on the right track and my working (if inelegant) solution is:
public void SetColor2(GridViewRow row, string columnName, int cellIndex)
{
if (row.RowType == DataControlRowType.DataRow)
{
int number = Convert.ToInt32(columnName);
if (number == 0)
{
row.Cells[cellIndex].Text = "";
return;
}
else if ((number > 0) && (number <= 74))
{
row.Cells[cellIndex].BackColor = System.Drawing.Color.Red;
row.Cells[cellIndex].ForeColor = System.Drawing.Color.Black;
return;
}
}
}
Usage:
protected void gv1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.DataItem != null)
{
DataRowView drv = (DataRowView)e.Row.DataItem;
SetColor2(e.Row, drv["A"].ToString(), 2);
SetColor2(e.Row, drv["B"].ToString(), 3);
etc...
}
}