Why foreach loop fails at last row of gridview? - c#

I have put a code to COLOR the background of GRIDVIEW Cell# 14 if cell's text != "nbsp;" and it does work except for the last row. It doesn't color the last row even it isn't equal to "nbsp;"
protected void grdviewCases_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
foreach (GridViewRow gr in grdviewCases.Rows)
{
if (gr.Cells[14].Text != " ")
{
gr.Cells[14].BackColor = Color.Red; ;
gr.Cells[14].ForeColor = Color.WhiteSmoke;
}
}
}
}

You need not loop rows in RowDataBound event, you may just use e object to reference each row
protected void grdviewCases_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (e.Row.Cells[14].Text != " ")
{
e.Row.Cells[14].BackColor = Color.Red; ;
e.Row.Cells[14].ForeColor = Color.WhiteSmoke;
}
}
}
For more details check system.web.ui.webcontrols.gridview.rowdatabound

Related

Sum a gridview_rowdatabount

Ok so i have 4 columns named actual and 4 columns named target, i need to sum all of the actual columns, and pass the total to a label... Can anybody help?
What i have so far but i know its incorrect..
public void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow) //checking the index of cells and changing the font colour
{
System.Data.DataRowView drv = (System.Data.DataRowView) e.Row.DataItem;
DataTable dt = drv.Row.Table;
for (int i = 0; i < e.Row.Cells.Count; i++)
{
if (dt.Columns[i].ColumnName.Contains("Actual"))
{
e.Row.Cells[i].ForeColor = Color.Red;
}
dt.Columns.Add("Total", typeof(Double));
foreach (DataRow row in dt.Rows)
{
int sum = row.Table.Columns<DataColumn>().Sum(dc => (int)row[dc]);
row.SetField("Total", sum);
labeltotal.Text = sum.ToString();
}
}
You can simply do that like this
Int32 total = 0;
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
total = total + Convert.ToInt32(e.Row.Cells[1].Text);
//here you can give the column no that you want to total like e.Row.Cells[1] for column 1
lblTotal.Text = total.ToString();
}
}

Highlight gridview row based on datatable values

I need to highlight gridview rows based on values from datatable.
I have highlighted values like if any particular cell values has met some conditions then I can highlight using this code.
if(int.Parse(DataBinder.Eval(e.Row.DataItem,"Risk").ToString()) > 100)
{
e.Row.BackColor = Color.FromName("#FAF7DA");
}
Now my questions is, in my rowdatabound event I want to check values in datatable and I need to highlight values in the gridview.
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataTable dt = DataRepository.highlightRow();
string[] strInactive = dt.AsEnumerable().Select(row => row.Field<string>("product_id")).ToArray();
foreach (GridViewRow row in gvProducts.Rows)
{
for (int i = 0; i < gvProducts.Columns.Count; i++)
{
if (gvProducts.Rows[0].Cells[0].Text.Contains("how to pass array values"))
{
e.Row.BackColor = System.Drawing.Color.Red;
}
}
}
}
}
For ex:
Here the datatable will return only one column values like this,10, 20, 20. Then I need to highlight rows of these values in the gridview.
you should be able to check e.Row.DataItem for values that meet your criteria
You can do something like this in the RowDataBound event:
if (e.Row.RowType == DataControlRowType.DataRow) {
DataRowView drv = (DataRowView) e.Row.DataItem;
if( drv("Risk") == <some condition> ) {
e.Row.BackColor = Drawing.Color.Black // :)
}
}
Perhaps this is what you are looking for:
private const System.Drawing.Color HIGHLIGHT = System.Drawing.Color.Yellow;
private const System.Drawing.Color NORMAL = System.Drawing.Color.White;
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataTable dt = DataRepository.highlightRow();
string[] strInactive = dt.AsEnumerable().Select(row => row.Field<string>("product_id")).ToArray();
foreach (var value in strInactive)
{
e.Row.BackColor = (e.Row.Cells[0].Text == value) ? HIGHLIGHT : NORMAL;
}
}
}
I do not know what is in your DataTable, so I don't know what you want to test for.

Calculate the sum of gridview column data and store its value in a variable

I am using RowDataBound Event to calculate the sum of a column data. The variable in which i am getting the sum of column values is becoming zero at the end of the rowdatabound event, because its initial value is zero. How can I store the sum of values in a variable to use its value outside the event. Thanks
int totSubTot = 0;
public double TotalAmount;
protected void gvShowOrder_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
totSubTot += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "SubTotal"));
}
else if (e.Row.RowType == DataControlRowType.Footer)
{
e.Row.Cells[2].Text = "Grand Total";
e.Row.Cells[2].Font.Bold = true;
e.Row.Cells[3].Text = totSubTot.ToString();
e.Row.Cells[3].Font.Bold = true;
TotalAmount = Convert.ToDouble(e.Row.Cells[3].Text);
}
}
Why not get the sum from data source?
var gridView = sender as GridView;
var dataSource = gridView.DataSource as IEnumerable<YourDataObject>;
e.Row.Cells[3].Text = dataSource.Sum(item => item.YourProperty).ToString();
Your logic seems to be off.
In your first if-statement you assign totSubTot to the DataItem, but in your else you are not assigning anything to it.
It probably only goes into one of your if/else if and thats why. Try this
if (e.Row.RowType == DataControlRowType.DataRow)
{
totSubTot += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "SubTotal"));
TotalAmount =Convert.ToDouble(totSubTot);
}
else if (e.Row.RowType == DataControlRowType.Footer)
{
totSubTot += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "SubTotal"));
TotalAmount =Convert.ToDouble(totSubTot);
e.Row.Cells[2].Text = "Grand Total";
e.Row.Cells[2].Font.Bold = true;
e.Row.Cells[3].Text = totSubTot.ToString();
e.Row.Cells[3].Font.Bold = true;
}
please try this
static int totSubTot = 0;
static double TotalAmount;
protected void gvShowOrder_RowDataBound(object sender, GridViewRowEventArgs e) {
if (e.Row.RowType == DataControlRowType.DataRow) {
totSubTot += Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "SubTotal"));
} else if (e.Row.RowType == DataControlRowType.Footer) {
e.Row.Cells[2].Text = "Grand Total";
e.Row.Cells[2].Font.Bold = true;
e.Row.Cells[3].Text = totSubTot.ToString();
e.Row.Cells[3].Font.Bold = true;
TotalAmount = Convert.ToDouble(e.Row.Cells[3].Text);
}
}

Disable last rows in a gridview

I have a gridview and i want to disable the last 5 rows of it how can i do it??below code is not working
protected void gview_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Enabled = e.Row.RowIndex <= 5; //for disabling last 4 rows
}
}
protected void gview_RowDataBound(object sender, GridViewRowEventArgs e)
{
GridView grid = sender as GridView;
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Enabled = grid.Rows.Count - e.Row.RowIndex > 4;
}
}
EDITED: Assuming your DataSource is DataTable, you can do something like this:
protected void gview_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Enabled = dataTable.Rows.Count - e.Row.RowIndex > 4;
}
}
i am assuming you are bnding dataset as datascurce to the gridview, so In RowDataBound bound add following code:
public static int count=0;
protected void grdview1_RowDataBound()
{
for(int i=0;i< ds.table[0].rows.count;i++)
{
count++;
if(count>(ds.table[0].rows.count-5))
{
e.Row.Enabled = false;
}
}
}

C# Iterate Over DataGridView & Change Row Color

I have a datagridview made up of multiple rows and columns.
I want to iterate through each row and check the contents of a specific column.
If that column contains the word "NO", I want to change the forecolor of the entire row to Red.
Here is an attempt at some code so far but It's certainly not working, starting to wonder If I need to iterate over every cell?
CODE:
foreach (DataGridViewRow dgvr in dataGridView1.Rows)
{
if (dgvr.Cells["FollowedUp"].Value.ToString() == ("No"))
{
dgvr.DefaultCellStyle.ForeColor = Color.Red;
}
}
hook up OnRowDataBound event then do stuff
ASPX (Grid):
<asp:.... OnRowDataBound="RowDataBound"..../>
Code Behind:
protected void RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowIndex == -1)
{
return;
}
if(e.Row.Cells[YOUR_COLUMN_INDEX].Text=="NO"){
e.Row.BackColor=Color.Red;
}
}
FOR WinForms:
hook the **DataBindingComplete** event and do stuff in it:
private void dataGridView1_DataBindingComplete(object sender,
DataGridViewBindingCompleteEventArgs e)
{
if (e.ListChangedType != ListChangedType.ItemDeleted)
{
DataGridViewCellStyle red = dataGridView1.DefaultCellStyle.Clone();
red.BackColor=Color.Red;
foreach (DataGridViewRow r in dataGridView1.Rows)
{
if (r.Cells["FollowedUp"].Value.ToString()
.ToUpper().Contains("NO"))
{
r.DefaultCellStyle = red;
}
}
}
}
On your DataGridView, handle the CellFormatting event:
dataGridView1.CellFormatting += new DataGridViewCellFormattingEventHandler(dataGridView1_CellFormatting);
Your event handler could then look like this:
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if(dataGridView1.Columns[e.ColumnIndex].Name == "FollowedUp" && e.Value != null && e.Value.ToString() == "No")
dataGridView1.Rows[e.RowIndex].DefaultCellStyle.ForeColor = Color.Red;
}
In this way you aren't 'iterating' over the rows -- simply changing the color with which they are painted/drawn when they become visible (and thus require formatting) in the grid.
public void ColourChange()
{
DataGridViewCellStyle RedCellStyle = null;
RedCellStyle = new DataGridViewCellStyle();
RedCellStyle.ForeColor = Color.Red;
DataGridViewCellStyle GreenCellStyle = null;
GreenCellStyle = new DataGridViewCellStyle();
GreenCellStyle.ForeColor = Color.Green;
foreach (DataGridViewRow dgvr in dataGridView1.Rows)
{
if (dgvr.Cells["FollowedUp"].Value.ToString().Contains("No"))
{
dgvr.DefaultCellStyle = RedCellStyle;
}
if (dgvr.Cells["FollowedUp"].Value.ToString().Contains("Yes"))
{
dgvr.DefaultCellStyle = GreenCellStyle;
}
}
}
Is it possible there are spaces or some other character as part of the cell value? If so try using the Contains method rather than straight equality.
if (dgvr.Cells["FollowedUp"].Value.ToString().Contains("No"))
This is the solution for Winforms:
private void HighlightRows()
{
DataGridViewCellStyle GreenStyle = null;
if (this.dgridv.DataSource != null)
{
RedCellStyle = new DataGridViewCellStyle();
RedCellStyle.BackColor = Color.Red;
for (Int32 i = 0; i < this.dgridv.Rows.Count; i++)
{
if (((DataTable)this.dgridv.DataSource).Rows[i]["col_name"].ToString().ToUpper() == "NO")
{
this.dgridv.Rows[i].DefaultCellStyle = RedCellStyle;
continue;
}
}
}
}
This code works fine for me:
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if ((string)row.Cells["property_name"].Value == UNKNOWN_PROPERTY_NAME)
{
row.DefaultCellStyle.BackColor = Color.LightSalmon;
row.DefaultCellStyle.SelectionBackColor = Color.Salmon;
}
}
Other than casting as a string rather than calling ToString I dont really see any difference so it could be a case sensitivity bug. Try using:
dgvr.Cells["FollowedUp"].Value.ToString().ToUpper() == "NO"
private void Grd_Cust_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
colorCode == 4 ? Color.Yellow : Color.Brown;
if (e.RowIndex < 0 || Grd_Cust.Rows[e.RowIndex].Cells["FollowedUp"].Value == DBNull.Value)
return;
string colorCode = Grd_Cust.Rows[e.RowIndex].Cells["FollowedUp"].Value.ToString();
e.CellStyle.BackColor = colorCode == "NO" ? Color.Red : Grd_Cust.DefaultCellStyle.BackColor;
}

Categories

Resources