简体   繁体   English

如何根据条件更改 DataGridView 的行颜色以检查日期是否过期

[英]How to change a row color of DataGridView based on Condition to check if Date Expired

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我想要实现的是根据下面代码中提到的条件动态更改datagridview行的颜色,这意味着如果到期日期大于当前日期,这意味着它已过期,则行将其颜色更改为红色 如果还有 30 天过期,则变为黄色

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;

            }
        }
    }

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 .为了实现你正在寻找的东西,你可以使用两个嵌套for ,一个循环你的查询结果(DataTable MrkExp),一个循环包含在你的dataGridView中的值。

Assuming both of your database's table and dataGridView have one Unique ID or field, you could check if they're equal.假设您的数据库表和 dataGridView 都有一个唯一 ID 或字段,您可以检查它们是否相等。

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.如果您没有唯一字段或主要字段,请考虑更新显示表结构的问题。

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这是我使用RowPrePaint事件实现的代码

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在我使用错误的CellFormatting事件并创建了一个RowPrePaint事件之前,在if语句声明要在if语句中使用的变量之前,我使用的代码显示了 rest。它就像一个魅力

My advice would be to use the event DataGridViewCell.CellFormatting for this.我的建议是为此使用事件 DataGridViewCell.CellFormatting It is called, whenever cell [x, y] needs to be formatted.只要单元格 [x, y] 需要格式化,它就会被调用。

Use DataBinding to easily access the data in your rows使用 DataBinding 轻松访问行中的数据

I don't know what kind of items you show in your DataGridView, let's assume it's a collection of price offers.我不知道您在 DataGridView 中显示的是什么类型的项目,我们假设它是价格优惠的集合。 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.在某个地方,您可以告诉需要显示 PriceOffer 的哪些列。 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:您还有一个属性来获取 PriceOffers 的初始集合:

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

And of course a property to attach these PriceOffers to the DataGridView当然还有将这些 PriceOffers 附加到 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 .操作员所做的所有更改:添加/删除/编辑 PriceOffers 都会在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;
        ...
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM