c# - 在用户编辑和输入单元格时更改 DataGridView 的单元格样式
问题描述
DataGridView
当用户正在编辑单元格时,我需要根据某些条件更改单元格的背景颜色。现在我只能BackColor
在单元格失去焦点后更改。
具体来说,当用户在单元格中键入时,我需要检查绑定到的DataTable
,DataGridView
以将用户键入的内容与相应单元格中 DataTable 中的值进行比较。如果不同,我需要将其更改BackColor
为黄色。如果用户将单元格中的值更改回 DataTable 中的原始值,我需要删除颜色。
我尝试弄乱该KeyPress
事件,但我不知道如何获取正在编辑的单元格的特定行/列索引,因此我可以根据相应DataTable
的行/列索引值正确检查它的值。
解决方案
这并不容易,您需要处理一些事情:
- 单元格编辑控件与单元格不同,因此在开始编辑时,找到编辑控件并通过将文本与数据源值进行比较来为其设置初始颜色。
- 当要显示编辑控件时,处理它的
TextChanged
事件并在TextChanged
事件处理程序中,将文本与数据源值进行比较,并根据该值对文本框进行着色。 - 当你完成编辑时,值不会推送到数据源,直到你离开记录或显式调用结束编辑后,所以当编辑结束时,将值推送到数据源。
- 处理单元格绘画并为单元格着色。
- 为新行使用不同的颜色(如果你喜欢)。它们与修改后的行不同,它们没有原始版本。
- 由于我们已经处理了单元格绘制,如果数据源中的值发生变化,单元格将被重新绘制。
这是屏幕截图:
这是一个工作示例:
public DataTable GetProducts()
{
var products = new DataTable();
products.Columns.Add("Id", typeof(int));
products.Columns.Add("Name", typeof(string));
products.Columns.Add("Price", typeof(int));
products.Rows.Add(1, "Product 1", 100);
products.Rows.Add(2, "Product 2", 200);
products.AcceptChanges();
return products;
}
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.AutoGenerateColumns = true;
dataGridView1.DataSource = GetProducts();
dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;
dataGridView1.EditingControlShowing += dataGridView1_EditingControlShowing;
dataGridView1.CellPainting += dataGridView1_CellPainting;
dataGridView1.CellBeginEdit += dataGridView1_CellBeginEdit;
dataGridView1.CellEndEdit += dataGridView1_CellEndEdit;
}
private void dataGridView1_CellEndEdit(object sender,
DataGridViewCellEventArgs e)
{
if (e.ColumnIndex < 0 || e.RowIndex < 0 || e.RowIndex == dataGridView1.NewRowIndex)
return;
var drv = dataGridView1.Rows[e.RowIndex].DataBoundItem as DataRowView;
if (drv != null)
{
drv.EndEdit();
}
}
private void dataGridView1_CellBeginEdit(object sender,
DataGridViewCellCancelEventArgs e)
{
if (e.ColumnIndex < 0 || e.RowIndex < 0 || e.RowIndex == dataGridView1.NewRowIndex)
return;
BeginInvoke(new Action(() =>
{
var textBox = dataGridView1.EditingControl as DataGridViewTextBoxEditingControl;
if (textBox != null)
{
SetEditingControlColor(textBox);
}
}));
}
private void dataGridView1_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex < 0 || e.RowIndex < 0 || e.RowIndex == dataGridView1.NewRowIndex)
return;
var drv = dataGridView1.Rows[e.RowIndex].DataBoundItem as DataRowView;
if (drv != null && drv.Row.HasVersion(DataRowVersion.Original))
{
var column = dataGridView1.Columns[e.ColumnIndex].DataPropertyName;
if (drv.Row[column, DataRowVersion.Current]
.Equals(drv.Row[column, DataRowVersion.Original]))
{
e.CellStyle.BackColor = Color.White;
}
else
{
e.CellStyle.BackColor = Color.Yellow;
}
return;
}
e.CellStyle.BackColor = Color.LimeGreen;
}
void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
var textBox = e.Control as DataGridViewTextBoxEditingControl;
if (textBox != null)
{
textBox.TextChanged -= textbox_TextChanged;
textBox.TextChanged += textbox_TextChanged;
}
}
private void textbox_TextChanged(object sender, EventArgs e)
{
var textBox = (DataGridViewTextBoxEditingControl)sender;
SetEditingControlColor(textBox);
}
void SetEditingControlColor(DataGridViewTextBoxEditingControl textBox)
{
var dgv = textBox.EditingControlDataGridView;
var drv = dgv.CurrentCell.OwningRow.DataBoundItem as DataRowView;
if (drv != null && drv.Row.HasVersion(DataRowVersion.Original))
{
var column = dgv.Columns[dgv.CurrentCell.ColumnIndex].DataPropertyName;
var value = drv.Row[column, DataRowVersion.Original];
if (textBox.Text.Equals($"{value}"))
{
textBox.BackColor = Color.White;
textBox.Parent.BackColor = Color.White;
}
else
{
textBox.BackColor = Color.Yellow;
textBox.Parent.BackColor = Color.Yellow;
}
return;
}
textBox.BackColor = Color.LimeGreen;
textBox.Parent.BackColor = Color.LimeGreen;
}
推荐阅读
- python - 在 Python 中加速插值
- java - Jackson objectMapper.treeToValue 将空字符串映射到 null 而不是空字符串
- google-sheets - Google 表格 - 创建一个按钮以在用户选择的列上运行
- java - 将 .war 文件添加到 Docker 映像并创建新映像以进行部署...失败
- python - 如何可视化卫星图像的随机森林分类?
- r - 循环遍历数据框名称并在 R 中绘图
- javascript - 使用快速文件上传后,多个文件上传仅上传第一个文件
- python - Combine two rows in csv using python
- python - 监控通过 Python win32.Dispatch('Outlook.Application') 发送的电子邮件?
- visual-studio - 强制 xUnit 测试作为控制台应用程序运行