Winforms 在选择更改时直接应用和验证绑定的DataGridViewComboxCell

Winforms 在选择更改时直接应用和验证绑定的DataGridViewComboxCell,winforms,validation,datagridview,combobox,Winforms,Validation,Datagridview,Combobox,我有一个windows窗体DataGridView,其中包含一些DataGridViewComboxCells,它们使用DataSource、DisplayMember和ValueMember属性绑定到源集合。当前,只有在我单击另一个单元格并且组合框单元格失去焦点后,组合框单元格才会提交更改(即,DataGridView.CellValueChanged) 理想情况下,在组合框中选择新值后,如何直接提交更改。此行为写入DataGridViewComboxEditingControl的实现中。谢天

我有一个windows窗体
DataGridView
,其中包含一些
DataGridViewComboxCell
s,它们使用
DataSource
DisplayMember
ValueMember
属性绑定到源集合。当前,只有在我单击另一个单元格并且组合框单元格失去焦点后,组合框单元格才会提交更改(即,
DataGridView.CellValueChanged


理想情况下,在组合框中选择新值后,如何直接提交更改。

此行为写入
DataGridViewComboxEditingControl的实现中。谢天谢地,它可以被推翻。首先,必须创建上述编辑控件的子类,覆盖
OnSelectedIndexChanged
方法:

protected override void OnSelectedIndexChanged(EventArgs e) {
    base.OnSelectedIndexChanged(e);

    EditingControlValueChanged = true;
    EditingControlDataGridView.NotifyCurrentCellDirty(true);
    EditingControlDataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
这将确保在组合框中的项目选择发生更改时,正确通知
DataGridView

然后,您需要子类化
datagridviewcomboxcell
并重写
EditType
属性,以从上面返回编辑控件子类(例如
returntypeof(MyEditingControl);
)。这将确保在单元格进入编辑模式时创建正确的编辑控件

最后,您可以将
DataGridViewComboxColumn
CellTemplate
属性设置为单元格子类的实例(例如
myDataGridViewColumn.CellTemplate=new MyCell();
)。这将确保网格中的每一行都使用正确类型的单元格。

我尝试使用,但它对附加单元格模板的时间很敏感。似乎我不能让设计视图连接到专栏,我必须自己做

相反,我使用了绑定源的PositionChanged事件,并从中触发了更新。这有点奇怪,因为控件仍处于编辑模式,并且数据绑定对象尚未获取选定的值。我只是自己更新了绑定对象

    private void bindingSource_PositionChanged(object sender, EventArgs e)
    {
        (MyBoundType)bindingSource.Current.MyBoundProperty = 
            ((MyChoiceType)comboBindingSource.Current).MyChoiceProperty;
    }

我正在成功地使用的一种更好的方法,而不是上面的子类化或有点不雅观的绑定源代码方法,是以下方法(很抱歉,它是VB,但是如果你不能从VB转换到C,你会有更大的问题:)

就这样

Private _currentCombo As ComboBox

Private Sub grdMain_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles grdMain.EditingControlShowing
    If TypeOf e.Control Is ComboBox Then
        _currentCombo = CType(e.Control, ComboBox)
        AddHandler _currentCombo.SelectedIndexChanged, AddressOf SelectionChangedHandler
    End If
End Sub

Private Sub grdMain_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grdMain.CellEndEdit
    If Not _currentCombo Is Nothing Then
        RemoveHandler _currentCombo.SelectedIndexChanged, AddressOf SelectionChangedHandler
        _currentCombo = Nothing
    End If
End Sub

Private Sub SelectionChangedHandler(ByVal sender As Object, ByVal e As System.EventArgs)
    Dim myCombo As ComboBox = CType(sender, ComboBox)
    Dim newInd As Integer = myCombo.SelectedIndex

    //do whatever you want with the new value

    grdMain.NotifyCurrentCellDirty(True)
    grdMain.CommitEdit(DataGridViewDataErrorContexts.Commit)
End Sub