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...
}
}
Related
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";
}
}
}
I want READONLY on text box using Boundsfield. So far enabled is working but it not carry value in rowupdating
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
var nopoject = ddlproject.SelectedValue.ToString();
Int32 curntMonth = Convert.ToInt32(DateTime.Now.ToString("MM"));
int Mont1 = curntMonth - 1;
var Comtext = "Rst" + Mont1.ToString();
GridView1.EditIndex = e.NewEditIndex;
BindData();
foreach (GridViewRow row in GridView1.Rows)
{
for (int i = 0; i < GridView1.Columns.Count; i++)
{
String headertext = GridView1.Columns[i].HeaderText;
String cellText = row.Cells[i].Text;
if (Comtext == "Rst1")
{
GridView1.Rows[e.NewEditIndex].Cells[i].Enabled = true;
}}}
Below code not working :
GridView1.Rows[e.NewEditIndex].Cells[i].Attributes.Add("readonly", "readonly");
GridView1.Rows[e.NewEditIndex].Cells[i].CssClass = "read-only";
Please advise. I want readonly on boundsfield programically when inline edit
Thank you
You can use this snippet.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
TextBox textBox = e.Row.Cells[0].Controls[0] as TextBox;
textBox.Enabled = false;
}
}
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowState == DataControlRowState.Edit || e.Row.RowState == DataControlRowState.Alternate)
{
//on you condition
TextBox txt = (TextBox)e.Row.FindControl("ControlID");
if(txt !=null)
{
txt.Attributes.Add("readonly", "readonly");
}
}
}
You can also make textbox readonly in row editing event as below.
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
var nopoject = ddlproject.SelectedValue.ToString();
Int32 curntMonth = Convert.ToInt32(DateTime.Now.ToString("MM"));
int Mont1 = curntMonth - 1;
var Comtext = "Rst" + Mont1.ToString();
GridView1.EditIndex = e.NewEditIndex;
BindData();
foreach (GridViewRow row in GridView1.Rows)
{
for (int i = 0; i < GridView1.Columns.Count; i++)
{
String headertext = GridView1.Columns[i].HeaderText;
String cellText = row.Cells[i].Text;
if (Comtext == "Rst1")
{
//GridView1.Rows[e.NewEditIndex].Cells[i].Enabled = true;
TextBox tx_chdets = (TextBox)GridView1.Rows[e.NewEditIndex].FindControl(“TextBox1”);
if(tx_chdets!=null)
{
tx_chdets.Readonly=true;
}
}
}
}
}
i have a datageidview which supposed to color the rows with contains specific value
private void dataGridView2_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
foreach (DataGridViewRow myrow in dataGridView2.Rows)
{
if (e.RowIndex != -1)
{
if (myrow.Cells[7].Value.ToString() == "Error")
{
myrow.DefaultCellStyle.BackColor = Color.Red;
}
else if (myrow.Cells[7].Value.ToString() == "NoError")
{
myrow.DefaultCellStyle.BackColor = Color.Green;
}
}
}
}
but i have a problem when the first row contains this value all the rows is colored with it's color
any help ??
The CellFormatting event is sent for all visible cells in the grid. You may have better luck using the data given in the event to change the color.
private void dataGridView2_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.RowIndex != -1)
{
if (dataGridView2.Rows[e.RowIndex].Cells[7].Value.ToString() == "Error")
{
e.CellStyle.BackColor = Color.Red;
}
else if (dataGridView2.Rows[e.RowIndex].Cells[7].Value.ToString() == "NoError")
{
e.CellStyle.BackColor = Color.Green;
}
}
}
I have a GridView and a list of items in a ListBox. Excluding the first column in the GridView.
I want to tooltip each and every header with the corresponding item in the ListBox. I mean the tooltip for GridView2.Columns[i].HeaderText = ListBox.Items[i].Tostring().
Here is what I have tried:
protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
for (int i = 1; i < GridView2.Columns.Count; i++)
{
String header = GridView2.Columns[i].HeaderText;
if (header.Length != 0)
{
e.Row.Cells[i].ToolTip = ListBox4.Items[i].ToString().Trim();
}
}
}
}
This is giving me an exception error: Index was out of range. Must be non-negative and less than the size of the collection.
Kindly help. Thank you.
protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
for (int i = 1; i < GridView2.Columns.Count; i++)
{
String header = GridView2.Columns[i].HeaderText;
if (header.Length != 0)
{
e.Row.Cells[i+1].ToolTip = ListBox4.Items[i].ToString().Trim();
}
}
}
}
Just suppose to use Cells[i+1] instead of Cells[i]
I have one table like employee and one of its row is 'status'.
If status value is 'approve' then I want to show that row in a green color
otherwise I want to show it in a red color.
I have tried following but it is not working
if (e.Row.RowType == DataControlRowType.Header)
{
string status = DataBinder.Eval(e.Row.DataItem, "IsApprove").ToString();
if (status == "pending")
{
e.Row.ForeColor = System.Drawing.Color.Red; // Change the row's Text color
}
}
ALSO THIS ONE
private void gvleavedetail_cellformatting(object sender, datagridviewcellformattingeventargs e)
{
// if the column is the artist column, check the
// value.
if (this.gvleavedetail.columns[e.columnindex].name == "artist")
{
if (e.value != null)
{
// check for the string "pink" in the cell.
string stringvalue = (string)e.value;
stringvalue = stringvalue.tolower();
if (stringvalue == "high")
{
e.cellstyle.backcolor = color.pink;
}
}
}
But in this case i'm getting error for datagridviewcellformattingeventargs
I'm using VS2010
hi all i got the solution plz c this one ;)
just write the following condition code on RowDataBound EVENT OF GRIDVIEW
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string status = Convert.ToString(DataBinder.Eval(e.Row.DataItem, "IsApprove"));
if (status == "pending")
{
e.Row.Cells[7].ForeColor = System.Drawing.Color.Yellow;
}
else if(status== "accept")
{
e.Row.Cells[7].ForeColor = System.Drawing.Color.Green;
}
else if (status == "reject")
{
e.Row.Cells[7].ForeColor = System.Drawing.Color.Red;
}
}
}