如何在用户编辑单元格时更改DataGridView的单元格样式

问题描述 投票:0回答:1

我需要根据特定条件更改DataGridView单元的背景色,因为用户正在编辑单元。现在,我只能在失去焦点后才能更改BackColor

[具体来说,当用户在一个单元格中键入内容时,我需要检查DataTable是否绑定了DataGridView,以便将用户所键入的内容与相应单元格的DataTable中的值进行比较。如果不同,我需要将BackColor更改为黄色。并且,如果用户将单元格中的值更改回DataTable中的原始值,则需要删除颜色。

我曾尝试弄乱KeyPress事件,但无法弄清楚如何获取正在编辑的单元格的特定行/列索引,因此我可以根据相应的DataTable行正确地检查它的值/列索引值。

c# datagridview keypress
1个回答
0
投票

这并不容易,您需要处理一些事情:

  • [单元格编辑控件与单元格不同,因此,在开始编辑时,找到编辑控件并通过将文本与数据源值进行比较来为其设置初始颜色。
  • 当编辑控件将要显示时,处理它的TextChanged事件,并在TextChanged事件处理程序中,将文本与数据源值进行比较,并根据其为文本框着色。
  • 完成编辑后,该值将不会推送到数据源,直到您离开记录或显式调用结束编辑之后,因此在编辑结束时,将值推送到数据源。
  • 处理单元格绘画并使单元格着色。
  • 对于新行,请使用其他颜色(如果需要)。它们与修改后的行不同,它们没有原始版本。
  • 由于我们已经处理了单元格绘制,如果数据源中的值发生更改,则将重新绘制单元格。

这里是屏幕截图:

enter image description here

这是一个有效的示例:

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.