什么事件在DataGridViewCell的组合框中捕获值的变化

本文关键字:变化 组合 事件 DataGridViewCell 什么 | 更新日期: 2023-09-27 17:50:11

我想处理在DataGridView单元格中ComboBox中的值发生变化时的事件。

CellValueChanged事件,但那一个不开火,直到我点击DataGridView内部的其他地方。

一个简单的ComboBox SelectedValueChanged在一个新值被选中后立即触发。

如何将侦听器添加到单元格内部的组合框中?

什么事件在DataGridViewCell的组合框中捕获值的变化

上面的答案让我走上了一条报春花之路。它不起作用,因为它会触发多个事件,只是不断添加事件。问题是,上面捕获了DataGridViewEditingControlShowingEvent,它没有捕获值的变化。所以每次你聚焦的时候它都会触发然后离开组合框不管它有没有改变

关于CurrentCellDirtyStateChanged的最后一个答案是正确的方法。我希望这能帮助人们避免掉进兔子洞。

下面是一些代码:
// Add the events to listen for
dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
dataGridView1.CurrentCellDirtyStateChanged += new EventHandler(dataGridView1_CurrentCellDirtyStateChanged);

// This event handler manually raises the CellValueChanged event 
// by calling the CommitEdit method. 
void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dataGridView1.IsCurrentCellDirty)
    {
        // This fires the cell value changed handler below
        dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }
}
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    // My combobox column is the second one so I hard coded a 1, flavor to taste
    DataGridViewComboBoxCell cb = (DataGridViewComboBoxCell)dataGridView1.Rows[e.RowIndex].Cells[1];
    if (cb.Value != null)
    {
         // do stuff
         dataGridView1.Invalidate();
    }
}

您还可以处理CurrentCellDirtyStateChanged事件,该事件在值更改时被调用,即使它没有提交。要获取列表中的选定值,您可以执行如下操作:

var newValue = dataGridView.CurrentCell.EditedFormattedValue;

下面的代码将触发dataGridView中comboBox中的选择事件:

public Form1()
{
    InitializeComponent();
    DataGridViewComboBoxColumn cmbcolumn = new DataGridViewComboBoxColumn();
    cmbcolumn.Name = "cmbColumn";
    cmbcolumn.HeaderText = "combobox column";
    cmbcolumn.Items.AddRange(new string[] { "aa", "ac", "aacc" });
    dataGridView1.Columns.Add(cmbcolumn);
    dataGridView1.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(dataGridView1_EditingControlShowing);
}
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    ComboBox combo = e.Control as ComboBox;
    if (combo != null)
    {
        combo.SelectedIndexChanged -= new EventHandler(ComboBox_SelectedIndexChanged);
        combo.SelectedIndexChanged += new EventHandler(ComboBox_SelectedIndexChanged);
    }
}
private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    ComboBox cb = (ComboBox)sender;
    string item = cb.Text;
    if (item != null)
        MessageBox.Show(item);
}

我已经实现了另一个解决方案,这似乎更响应(例如…更快,更少的点击)比上面的Mitja Bonca。虽然有时组合框关闭得很快。它使用currentcelldirtystatechange和CellMouseDown回调

private void myGrid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (myGrid.CurrentCell is DataGridViewComboBoxCell)
    {
        myGrid.CommitEdit(DataGridViewDataErrorContexts.Commit);
        myGrid.EndEdit();
    }
}
private void myGrid_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    if (myGrid.Rows[e.RowIndex].Cells[e.ColumnIndex] is DataGridViewComboBoxCell)
    {
        myGrid.CurrentCell = myGrid.Rows[e.RowIndex].Cells[e.ColumnIndex];
        myGrid.BeginEdit(true);
        ((ComboBox)myGrid.EditingControl).DroppedDown = true; // Tell combobox to expand
    }
}
ComboBox cmbBox = (ComboBox)sender;                
MessageBox.Show(cmbBox.SelectedValue.ToString());