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

时间:2011-04-13 17:09:28

标签: c# .net datagridview combobox event-handling

我希望在ComboBox单元格中的DataGridView中更改值时处理该事件。

CellValueChanged事件,但在我点击DataGridView内的其他地方之前,该事件才会触发。

选择新值后,会立即触发一个简单的ComboBox SelectedValueChanged

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

5 个答案:

答案 0 :(得分:45)

上面的回答让我在报春花路上走了一段时间。它不起作用,因为它导致多个事件触发并且只是不断添加事件。问题是上面捕获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 (this.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();
        }
     }

答案 1 :(得分:13)

这是代码,它将触发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);
    }

答案 2 :(得分:13)

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

var newValue = dataGridView.CurrentCell.EditedFormattedValue;

答案 3 :(得分:0)

我已经实施了另一种解决方案,它似乎比上面的 Mitja Bonca 的响应更快(例如,更快且点击次数更少)。虽然有时组合框会很快关闭。这使用 CurrentCellDirtyStateChanged 和 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
    }
}

答案 4 :(得分:-3)

ComboBox cmbBox = (ComboBox)sender;                
MessageBox.Show(cmbBox.SelectedValue.ToString());