Remove Gridview row in rowDataBound event asp.net c# - c#

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;
}
}

Related

Adding second class to gridview row in RowDataBound

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";
}
}
}

Gridview index out of range when rows are returning

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";
}

How can i find Last row in a gridview on RowDataBound

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;
}

Unable to set cell colour on a gridview

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;
}

How to add a numeric order to the GridView using RowDataBound?

I am a new ASP.NET developer and I am trying to change the value of the first cell in each row in the GridVie by giving it a number starting from 1. It means that I want to add order to the list of things that will be displayed in the GridView.
I am using GridView RowDataBound method but now I don't know to set the limit of the for loop in it. Could anyone help me with this?
My code-behind:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow) {
for(int i=1, i<; i++)
e.Row.Cells[0].Text = i;
}
}
If your requirement is "change the value of the first cell in each row", it would be more like:
private int _rowIndex=0;
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow) {
e.Row.Cells[0].Text = _rowIndex.ToString();
_rowIndex++;
}
}
You can try this, it will return of cell count:
int cells = ((TableRow) (e.Row)).Cells.Count;

Categories