Home > Net >  How to change a row color of DataGridView based on Condition to check if Date Expired
How to change a row color of DataGridView based on Condition to check if Date Expired

Time:10-10

What I want to achieve is to dynamically change the color of the row of datagridview based on a condition that is mentioned in the code below which means if the Expiry Date is greater than the current date which means its expired then the Row changed its color to red And if 30 days remain in Expiration than turn yellow

private void ViewMedicine_DataGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
        
        if (Dont know what to write here)
        {
            foreach (DataGridViewRow row in ViewMedicine_DataGrid.Rows) 
            {
                row.DefaultCellStyle.BackColor = Color.Red;
                row.DefaultCellStyle.ForeColor = Color.White;

            }
        }
    }

CodePudding user response:

In order to achieve what you're looking for, you could use two nested for, one to loop your results from the query (DataTable MrkExp), one to loop the values contained in your dataGridView.

Assuming both of your database's table and dataGridView have one Unique ID or field, you could check if they're equal.

To achieve that:

for (int i = 0; i < ViewMedicine_DataGrid.Rows.Count; i  )
                {
                    for (int j = 0; j < MrkExp.Rows.Count; j  )
                    {
                        if (ViewMedicine_DataGrid.Rows[i].Cells[0].Value != null)
                        {
                            if (ViewMedicine_DataGrid.Rows[i].Cells[0].Value == MrkExp.Rows[j]["UNIQUE_FIELD"])
                            {
                                ViewMedicine_DataGrid.Rows[i].DefaultCellStyle.BackColor = Color.Red;
                                ViewMedicine_DataGrid.Rows[i].DefaultCellStyle.ForeColor = Color.White;
                            }
                        }
                    }
                }

If you haven't got a unique field or primary, consider updating your question showing your table's structure.

CodePudding user response:

Finally, after a little brainstorming into the code and research a bit I got successful in getting the desired result. Here's what I code to made it possible using a RowPrePaint Event

private void ViewMedicine_DataGrid_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
        {
            var ExpiryDate = Convert.ToDateTime(ViewMedicine_DataGrid.Rows[e.RowIndex].Cells[7].Value);
            var TodayDate = DateTime.Today;
            var Expired = ExpiryDate >= TodayDate;
            var ExpiredToBe = ExpiryDate >= TodayDate.AddDays(-30);
            if (Expired)
            {
                ViewMedicine_DataGrid.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Red;
            }
            else if (ExpiredToBe)
            {
                ViewMedicine_DataGrid.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Yellow;
            }
        }

Before I was using a CellFormatting event which was wrong and Created a RowPrePaint Event and before if statements declared variables to be used in if Statement and the code I used shows the rest. It works like a charm

CodePudding user response:

My advice would be to use the event DataGridViewCell.CellFormatting for this. It is called, whenever cell [x, y] needs to be formatted.

Use DataBinding to easily access the data in your rows

I don't know what kind of items you show in your DataGridView, let's assume it's a collection of price offers. Each price offer has an expiry date:

class PriceOffer
{
    public DateTime ExpiryDate {get; set;}
    ...
}

Somewhere you tell which columns of the PriceOffer needs to be shown. Probably in the constructor:

InitializeComponent();

this.ColumnStartDate.DataPropertyName = nameof(PriceOffer.StartDate);
this.ColumnExpiryDate.DataPropertyName = nameof(PriceOffer.ExpiryDate);
this.ColumnPrice.DataPropertyName = nameof(PriceOffer.Price);
...

You also have a property to get your initial collection of PriceOffers:

IEnumerable<PriceOffer> FetchPriceOffersToDisplay(...)
{
    return ...
}

And of course a property to attach these PriceOffers to the DataGridView

BindingList<PriceOffer> DisplayedPriceOffers
{
    get => return (BindingList<PriceOffer>)this.dataGridView1.DataSource;
    set => this.dataGridView1.DataSource = value;
}

Initialize when the form is loaded

void OnFormLoad(object sender, ...)
{
    this.DisplayedPriceOffers = new BindingList<PriceOffer>(
        this.FetchPriceOffersToDisplay().ToList());
}

All changes that the operator makes: add / remove / edit PriceOffers are automatically updated in this.DisplayedPriceOffers.

Back to your question

private void dataGridView1_CellFormatting(object sender, 
    DataGridViewCellFormattingEventArgs e)
{

    DataGridViewRow row = this.dataGridView1.Rows[e.RowIndex];
    PriceOffer priceOffer = (PriceOffer)row.DataboundItem;
    
    if (DateTime.Today > priceOffer.ExpiryDate)
    {
        this.ColorRowExpired(row);
    }
    else
    {
        this.ColorRowNotExpired(row);
    }
}

void ColorRowExpired(DataGridViewRow row)
{
    foreach (DataGridViewCell cell in row.Cells)
    {
        cell.BackColor = ExpiredCellBackColor;
        ...
    }
}
  • Related