如何根据条件更改 DataGridView 的行颜色以检查日期是不是过期
Posted
技术标签:
【中文标题】如何根据条件更改 DataGridView 的行颜色以检查日期是不是过期【英文标题】:How to change a row color of DataGridView based on Condition to check if Date Expired如何根据条件更改 DataGridView 的行颜色以检查日期是否过期 【发布时间】:2021-10-08 11:08:17 【问题描述】:我想要实现的是根据下面代码中提到的条件动态更改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;
【问题讨论】:
我对你的陈述感到困惑……“如果 E_Date(到期日)大于当前日期,则意味着它已过期”……? ... 这似乎倒退了,应该是“如果 E_Date 小于当前日期,则 E_Date 已过期” ...我错过了什么吗?在任何一种情况下,检查日期是在“当前日期”之前还是之后都会看起来像……if (E_Date.Date < DateTime.Now.Date) // E_Date is expired ;
@JohnG 我已经对问题进行了更改,因为之前由于 SQL 查询部分而造成混淆,并使其变得简单,因此不会混淆。
@JohnG 在我解决了这个问题时也发布了答案请检查
您可能需要注意...将代码放入网格RowPrePaint
事件意味着即使日期没有更改,代码也会检查日期并为行着色。示例...当用户“滚动”网格时,网格RowPrePaint
事件将触发并检查日期并为行着色,当它已经是正确的颜色时。您应该小心将代码放入哪个网格事件,以避免不必要地执行它。这可能会导致 UI 迟缓。
另外,如果日期在当前日期之后,我仍然不明白如何“过期”。这对我来说似乎倒退了……但是,如果它对你有用,那就去吧。
【参考方案1】:
为了实现您要查找的内容,您可以使用两个嵌套的 for
,一个循环查询 (DataTable MrkExp) 的结果,一个循环循环您的 dataGridView
中包含的值。
假设您的数据库表和 dataGridView 都有一个唯一 ID 或字段,您可以检查它们是否相等。
要实现这一点:
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;
如果您没有唯一字段或主要字段,请考虑更新您的问题以显示您的表结构。
【讨论】:
在我解决了这个问题时发布了答案请检查【参考方案2】:最后,在对代码进行了一些头脑风暴并进行了一些研究之后,我成功地获得了预期的结果。这是我使用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;
在我使用错误的CellFormatting
事件并创建RowPrePaint
事件之前,在if
语句之前声明要在if
语句中使用的变量,我使用的代码显示了其余部分。它就像一个魅力
【讨论】:
【参考方案3】:我的建议是为此使用event DataGridViewCell.CellFormatting。每当需要格式化单元格 [x, y] 时都会调用它。
使用 DataBinding 轻松访问行中的数据
我不知道您在 DataGridView 中显示什么样的项目,让我们假设它是价格优惠的集合。每个报价都有一个有效期:
class PriceOffer
public DateTime ExpiryDate get; set;
...
您在某处告诉需要显示 PriceOffer 的哪些列。可能在构造函数中:
InitializeComponent();
this.ColumnStartDate.DataPropertyName = nameof(PriceOffer.StartDate);
this.ColumnExpiryDate.DataPropertyName = nameof(PriceOffer.ExpiryDate);
this.ColumnPrice.DataPropertyName = nameof(PriceOffer.Price);
...
您还有一个属性来获取您的 PriceOffers 初始集合:
IEnumerable<PriceOffer> FetchPriceOffersToDisplay(...)
return ...
当然还有将这些 PriceOffers 附加到 DataGridView 的属性
BindingList<PriceOffer> DisplayedPriceOffers
get => return (BindingList<PriceOffer>)this.dataGridView1.DataSource;
set => this.dataGridView1.DataSource = value;
加载表单时初始化
void OnFormLoad(object sender, ...)
this.DisplayedPriceOffers = new BindingList<PriceOffer>(
this.FetchPriceOffersToDisplay().ToList());
操作员所做的所有更改:添加/删除/编辑 PriceOffers 都会在this.DisplayedPriceOffers
中自动更新。
回到你的问题
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;
...
【讨论】:
以上是关于如何根据条件更改 DataGridView 的行颜色以检查日期是不是过期的主要内容,如果未能解决你的问题,请参考以下文章
如何使用来自底层绑定源的行对 datagridview 行执行样式更改?