I have a datagrid called dgMember_Grade that takes its data from a stored procedure.
One of its columns represent a date called vacationStart.
I want to color the rows based on cell value, but it gives me an error on the foreach line:
Cannot convert type 'char' to 'System.Windows.Forms.DataGridViewCell'
I tried the code:
foreach (DataGridViewRow Myrow in dgMember_Grade.Rows)
{
foreach (DataGridViewCell cell in Myrow.Cells[26].Value.ToString()) // error on foreach
{
if (cell != null)
{
DateTime date = DateTime.Now;
DateTime expiredate = DateTime.Parse(Myrow.Cells[26].Value.ToString());
if (expiredate < date)
{
Myrow.DefaultCellStyle.BackColor = Color.Red;
}
else
{
Myrow.DefaultCellStyle.BackColor = Color.Green;
}
}
}
}
Here is the code you can use:
foreach (DataGridViewRow Myrow in dgMember_Grade.Rows)
{
var cellValue = Myrow.Cells[26].Value;
if (cellValue == null || cellValue == DBNull.Value)
continue;
DateTime expiredate = Convert.ToDateTime(cellValue);
if (expiredate < DateTime.Now)
{
Myrow.DefaultCellStyle.BackColor = Color.Red;
}
else
{
Myrow.DefaultCellStyle.BackColor = Color.Green;
}
}
Note:
You don't need 2 loops, You can simply use a loop betwen Rows and apply what you need based on Myrow.Cells[26].Value
You can use events like CellFormatting or CellPainting or RowPrePaint to apply formatting.
If you already know an index of the cell.
May be you are trying to do this:
foreach (DataGridViewRow Myrow in dgMember_Grade.Rows)
{
if (Myrow.Cells[26].Value == null) {
continue;
}
DateTime expiredate = DateTime.Parse(Myrow.Cells[26].Value.ToString());
if (expiredate < DateTime.Now)
{
Myrow.DefaultCellStyle.BackColor = Color.Red;
}
else
{
Myrow.DefaultCellStyle.BackColor = Color.Green;
}
}
Related
I'm trying to change the color of the row in a datagridviewer based on the text that is in one of the columns. I'm getting the error: Object reference not set to an instance of an object on the line of the first if statement. I filled in the datagridviewer based on a datasource which the code is also below.
void ChangeDataGridViewColor()
{
foreach (DataGridViewRow Row in datagridviewTreatmentPrep.Rows)
{
if (Row.Cells["Primary Onc"].Value.ToString() == "JMK")
{
Row.DefaultCellStyle.BackColor = Color.Green;
}
if (Row.Cells["Primary Onc"].Value.ToString() == "DBF")
{
Row.DefaultCellStyle.BackColor = Color.Orange;
}
else
{
Row.DefaultCellStyle.BackColor = Color.White;
}
}
}
void FillDataGridViewTreatmentPrep()
{
string constring = "datasource = RadOncViewerDatabase.db";
string TreatPrepQuery = "SELECT * FROM TreatmentPrep";
SQLiteConnection connectionstring = new SQLiteConnection(constring);
connectionstring.Open();
DataTable dsTreatPrep = new DataTable();
SQLiteDataAdapter adapterTreatPrep = new SQLiteDataAdapter(TreatPrepQuery, constring);
adapterTreatPrep.Fill(dsTreatPrep);
datagridviewTreatmentPrep.DataSource = dsTreatPrep;
//datagridviewTreatmentPrep.BindingContext = new BindingContext();
//this.datagridviewTreatmentPrep.DataSource = dsTreatPrep.Tables[0].DefaultView.ToTable(true, "Patient_Name");
}
Use the the RowPrePaint event, and don't use .ToString() on objects that can be null:
private void dataGridView1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
if (e.RowIndex < 0) return;
var row = (sender as DataGridView).Rows[e.RowIndex];
string value = Convert.ToString(row.Cells["Primary Onc"].Value);
//or in VS 2015: string value = row.Cells["Primary Onc"].Value?.ToString();
if (value == "JMK")
row.DefaultCellStyle.BackColor = Color.Green;
else if (value == "DBF")
row.DefaultCellStyle.BackColor = Color.Orange;
else
row.DefaultCellStyle.BackColor = Color.White;
}
Below is the code I have tested and it works as expected. Sorry for the delay.
foreach (DataGridViewRow Row in dataGridView1.Rows) {
DataRowView drv = (DataRowView)Row.DataBoundItem;
if (drv != null) {
if (drv.Row["Primary Onc"].ToString() == "JMK") {
Row.DefaultCellStyle.BackColor = Color.Green;
}
else {
if (drv.Row["Primary Onc"].ToString() == "DBF") {
Row.DefaultCellStyle.BackColor = Color.Orange;
}
else {
Row.DefaultCellStyle.BackColor = Color.White;
}
}
}
}
Hope this helps.
you must use DataGridViewCellStyle class
my solution:
int max = dgv.Rows.Count;
DataGridViewCellStyle style;
for (int i = 0; i < max; i++)
for (int j = 2; j < dgv.Columns.Count; j++)
if (dgv[j, i].Value.ToString() == "")
{
style = dgv[j, i].Style;
style.BackColor = Color.Red;
dgv[j, i].Style = style;
}
I want with a condition :
all rows have bool_badge =0 : color with RED
all rows have bool_badge=1 : color with ForestGreen
I have a code Correct BUT just when i click for a cell specific
My code:
foreach (DataGridViewRow dr in dataGridView1.Rows)
{
int row = this.dataGridView1.CurrentCell.RowIndex;
string valeur = dataGridView1[2, row].Value.ToString();
if (valeur == "0")
{
dataGridView1.DefaultCellStyle.SelectionBackColor = Color.Red;
}
else
{
dataGridView1.DefaultCellStyle.SelectionBackColor = Color.ForestGreen;
}
}
The Result :
1) `
2)
But I want when i execute my application , the test begin if bool_badge 0 or 1, and i have for all the gridview : color RED or ForestGreen ,
I try this code:
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
string valeur = dataGridView1[2, i].Value.ToString();
if (valeur == "0")
{
dataGridView1.DefaultCellStyle.SelectionBackColor = Color.Red;
}
else
{
dataGridView1.DefaultCellStyle.SelectionBackColor = Color.ForestGreen;
}
}
But i have ERROR!
this is :
How can i fix it?
Very thanks,
You can use Datagridview's Cell_Formatting event.
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (dataGridView1.Columns[e.ColumnIndex].HeaderText == "bool_badge" && dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value != null)
// if the column is bool_badge and check null value for the extra row at dgv
{
if (dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString() == "0")
{
dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Red;
}
if (dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString() == "1")
{
dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.ForestGreen;
}
}
}
Result will be,
Hope helps,
You should use .Rows and .Cells properties.
string valeur = dataGridView1.Rows[i].Cells[2].Value.ToString();
For helping you debugging don't do Value.ToString(); just
var value = dataGridView_XXX.Rows[rowNumber].Cells[i].value;
And
if (value == null) display your row/column index
else dataGridView_XXX.Rows[rowNumber].DefaultCellStyle.BackColor = xxx;
I have this part of code, but not working..
foreach (DataGridViewRow row in dg1.Rows)
{
var now = DateTime.Now.Day;
var expirationDate = DateTime.Parse(row.Cells[2].Value.ToString()).Day;
if (now == expirationDate)
{
row.DefaultCellStyle.BackColor = Color.Red;
}
}
Not good idea to compare classes/structs like that(with == operator)
try using
if(DateTime.Compare(now, expirationDate) == 0)
Your problem is not the comparison you're performing (as others are referring), but it would be better to compare Date using DateTime.Compare method.
The problem is you're not checking for NewRow. It causes exception when you try to read an empty Row.
foreach (DataGridViewRow row in dg1.Rows)
{
if (!row.IsNewRow)
{
//your code
}
}
Have you tried replacing foreach with for?
for (int i = 0; i < dg1.Rows.Length; i++)
{
var now = DateTime.Now.Day;
var expirationDate = DateTime.Parse(dg1.Rows[i].Cells[2].Value.ToString()).Day;
if (now == expirationDate)
{
dg1.Rows[i].DefaultCellStyle.BackColor = Color.Red;
}
}
The collection used in foreach is immutable.
i use this code for focus row which match text in search text box.now how can i use % like % criteria for this code
foreach (DataGridViewRow row in GdvDetails.Rows)
{
var cellValue = row.Cells["Bunch Component"].Value;
if (cellValue != null && cellValue.ToString() == txtSearch.Text)
{
GdvDetails.Rows[row.Index].DefaultCellStyle.BackColor = Color.Yellow;
}
else
{
GdvDetails.Rows[row.Index].DefaultCellStyle.BackColor = Color.Empty;
}
}
try this
foreach (DataGridViewRow row in GdvDetails.Rows)
{
var cellValue = row.Cells["Bunch Component"].Value;
if (cellValue != null)
{
if ( cellValue.ToString().Contains(txtSearch.Text))
{
GdvDetails.Rows[row.Index].DefaultCellStyle.BackColor = Color.Yellow;
}
else
{
GdvDetails.Rows[row.Index].DefaultCellStyle.BackColor = Color.Empty;
}
}
}
My code works for changing color in rows, but I need to make correct if statement. In cell[0] I have date value "2013.03.20". This date means product expired date.
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells[0](dont know how write))
{
row.DefaultCellStyle.BackColor = Color.Red;
}
}
Example:
Today is 2013.03.10
Product expired date is 2013.03.20.
Last 7 days of product expiry will give Yellow color. (i.e. from 13th till 20th)
When product is expired, I want to show it as Red.
Something like this (off the top of my head with no Visual Studio so forgive any minor syntax errors). You would probably need to be a bit more robust with the DateTime conversion to handle nulls, invalid dates etc. You can tweak the conditions to match your exact requirements:
foreach (DataGridViewRow row in dataGridView1.Rows)
switch (Convert.ToDatetime(row.Cells[0].ToString()))
{
case > DateTime.Today:
row.DefaultCellStyle.BackColor = SomeColor;
break;
case == DateTime.Today:
row.DefaultCellStyle.BackColor = SomeColor;
break;
case else:
row.DefaultCellStyle.BackColor = SomeColor;
break;
}
As Simon said you should also handle incorrect date format for DateTime.
foreach (DataGridViewRow row in dataGridView1.Rows)
{
var now = DateTime.Now;
var expirationDate = DateTime.Parse(row.Cells[0].Value.ToString());
var sevenDayBefore = expirationDate.AddDays(-7);
if (now > sevenDayBefore && now < expirationDate)
{
row.DefaultCellStyle.BackColor = Color.Yellow;
}
else if (now > expirationDate)
{
row.DefaultCellStyle.BackColor = Color.Red;
}
}
Try this example.
DateTime currentToday = (DateTime)this.dataGridView1.Rows[e.RowIndex].Cells["Date"].Value;
if (currentToday <= DateTime.Now.Date)
{
e.CellStyle.ForeColor = Color.Red; //Font Color
e.CellStyle.SelectionForeColor = Color.Red; //Selection Font color
}
You can use RowDataBound event handler instead of using foreach. I think using RowDataBound event handler is for those things.
public void dataGridView1_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
Product currentProduct = e.Item.DataItem as Product;
TimeSpan diffDate = DateTime.Now - currentProduct.ExpireDate;
if (dateDiff < TimeSpan.FromDays(0))
{
row.DefaultCellStyle.BackColor = Color.Yellow;
}
else if (dateDiff < TimeSpan.FromDays(7))
{
row.DefaultCellStyle.BackColor = Color.Red;
}
}
}