在选择更改时直接应用并验证绑定的DataGridViewComboBoxCell

时间:2010-10-26 20:42:30

标签: winforms validation datagridview combobox

我有一个Windows窗体DataGridView,其中包含使用DataGridViewComboBoxCellDataSourceDisplayMember属性绑定到源集合的一些ValueMember。目前,只有在我点击另一个单元格并且组合框单元失去焦点后,组合框单元才会提交更改(即DataGridView.CellValueChanged被提升)。

如果在组合框中选择了新值后,我将如何直接提交更改。

3 个答案:

答案 0 :(得分:1)

此行为将写入DataGridViewComboBoxEditingControl的实现中。值得庆幸的是,它可以被覆盖。首先,您必须创建上述编辑控件的子类,覆盖OnSelectedIndexChanged方法:

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

    EditingControlValueChanged = true;
    EditingControlDataGridView.NotifyCurrentCellDirty(true);
    EditingControlDataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

这将确保DataGridView在组合框中的项目选择更改时得到适当的通知。

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

最后,您可以将CellTemplate的{​​{1}}属性设置为单元子类的实例(例如DataGridViewComboBoxColumn)。这将确保为网格中的每一行使用正确类型的单元格。

答案 1 :(得分:0)

我尝试使用Bradley's suggestion,但它对您附加单元格模板时很敏感。看起来我不能让设计视图连接到列,我必须自己做。

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

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

答案 2 :(得分:0)

实现这一目标的一个更好的方法,我成功使用而不是子类化或上面的有点不优雅的绑定源方法,如下(对不起它的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

就是这样。