WinForms/.NET Framework:基于ValidationResult优雅格式化DataGridView单元格
WinForms DataGridView 基于CustomValidationResult状态的单元格格式化方案
方案一:利用CellFormatting事件(快速实现)
这是最直接的方式,通过监听DataGridView的CellFormatting事件,在单元格渲染时根据绑定对象的CustomValidationResult.State动态设置样式。
实现步骤:
- 给目标DataGridView注册
CellFormatting事件(可在设计器事件面板添加,或代码手动绑定)。 - 在事件处理方法中:
- 过滤表头行与空数据行,避免空引用异常。
- 获取当前行绑定的自定义对象,取出对应的
CustomValidationResult。 - 根据
State属性设置单元格背景色、前景色,正常状态恢复默认样式。
代码示例:
// 假设自定义数据对象与验证结果定义 public enum ValidationState { Normal, Warning, Error } public class CustomValidationResult { public ValidationState State { get; set; } public string Message { get; set; } } public class CustomDataObject { public string DataProperty { get; set; } public CustomValidationResult ValidationResult { get; set; } } // CellFormatting事件处理方法 private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { // 跳过表头和无数据行 if (e.RowIndex < 0 || dataGridView1.Rows[e.RowIndex].DataBoundItem == null) return; var boundItem = dataGridView1.Rows[e.RowIndex].DataBoundItem as CustomDataObject; if (boundItem?.ValidationResult == null) return; // 根据验证状态设置样式 switch (boundItem.ValidationResult.State) { case ValidationState.Error: e.CellStyle.BackColor = Color.Red; e.CellStyle.ForeColor = Color.White; break; case ValidationState.Warning: e.CellStyle.BackColor = Color.Orange; e.CellStyle.ForeColor = Color.Black; break; default: // 恢复默认样式,防止样式残留 e.CellStyle.BackColor = dataGridView1.DefaultCellStyle.BackColor; e.CellStyle.ForeColor = dataGridView1.DefaultCellStyle.ForeColor; break; } }
注意事项:
- 若仅需给特定列应用样式,可添加列索引判断:
if (e.ColumnIndex == dataGridView1.Columns["TargetColumn"].Index)。 - 必须在
Normal状态恢复默认样式,否则滚动或刷新时会导致样式错误复用。
方案二:自定义DataGridViewColumn(复用场景)
如果多个DataGridView或列需要相同的验证样式逻辑,可以自定义列类型,将样式逻辑封装到列中,避免重复写事件。
代码示例:
public class ValidatedDataGridViewTextBoxColumn : DataGridViewTextBoxColumn { protected override void OnCellFormatting(DataGridViewCellFormattingEventArgs e) { base.OnCellFormatting(e); if (e.RowIndex < 0 || DataGridView.Rows[e.RowIndex].DataBoundItem == null) return; var boundItem = DataGridView.Rows[e.RowIndex].DataBoundItem as CustomDataObject; if (boundItem?.ValidationResult == null) return; switch (boundItem.ValidationResult.State) { case ValidationState.Error: e.CellStyle.BackColor = Color.Red; e.CellStyle.ForeColor = Color.White; break; case ValidationState.Warning: e.CellStyle.BackColor = Color.Orange; e.CellStyle.ForeColor = Color.Black; break; default: e.CellStyle.BackColor = DataGridView.DefaultCellStyle.BackColor; e.CellStyle.ForeColor = DataGridView.DefaultCellStyle.ForeColor; break; } } }
使用方式:
- 在设计器中,将DataGridView的列类型替换为自定义的
ValidatedDataGridViewTextBoxColumn; - 或通过代码创建列并添加到DataGridView:
dataGridView1.Columns.Add(new ValidatedDataGridViewTextBoxColumn { DataPropertyName = "DataProperty", HeaderText = "目标列" });
扩展:按属性单独验证的场景
如果自定义对象中每个属性都有独立的CustomValidationResult(比如NameValidation、ValueValidation),可在CellFormatting事件中根据列名匹配对应的验证结果:
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { if (e.RowIndex < 0 || dataGridView1.Rows[e.RowIndex].DataBoundItem == null) return; var boundItem = dataGridView1.Rows[e.RowIndex].DataBoundItem as CustomDataObject; if (boundItem == null) return; CustomValidationResult validationResult = null; // 根据列名匹配对应属性的验证结果 switch (dataGridView1.Columns[e.ColumnIndex].Name) { case "NameColumn": validationResult = boundItem.NameValidation; break; case "ValueColumn": validationResult = boundItem.ValueValidation; break; } if (validationResult == null) return; // 样式设置逻辑同方案一 switch (validationResult.State) { case ValidationState.Error: e.CellStyle.BackColor = Color.Red; e.CellStyle.ForeColor = Color.White; break; case ValidationState.Warning: e.CellStyle.BackColor = Color.Orange; e.CellStyle.ForeColor = Color.Black; break; default: e.CellStyle.BackColor = dataGridView1.DefaultCellStyle.BackColor; e.CellStyle.ForeColor = dataGridView1.DefaultCellStyle.ForeColor; break; } }
内容的提问来源于stack exchange,提问作者lhiapgpeonk
相关产品推荐
相关产品推荐

