设置新的DataGridViewComboBoxCell,用于在同一列和行

时间:2017-02-09 12:56:42

标签: vb.net winforms datagridview datagridviewcomboboxcell datagridviewtextboxcell

我有DataGridView并且有一个DataGridViewTextBoxColumn,用户可以在其中键入数字,在输入数字后,我会执行搜索以找到该数字下的先前记录。

我想显示这些记录,以便用户可以选择其中一个,或保持值类型,这意味着他想创建一个新记录。

为此,我想在用户输入完成后用这些选项替换DataGridViewTextBoxCell的每个DataGridViewComboBoxCell

但是,当我尝试使用此替换时,它会引发此异常:" System.InvalidOperationException"在System.Windows.Forms.dll中。附加信息:该操作无效,因为它导致重新调用函数SetCurrentCellAddressCore。

以下是我的代码(我已尝试处理CellLeave而不是CellValidated):

Private Sub DataGridViewDebitos_CellValidated(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridViewDebitos.CellValidated
    DataGridViewDebitos.EndEdit(DataGridViewDataErrorContexts.Commit)
    If e.ColumnIndex = ColumnDebito.Index Then
        Dim cellDebito = DataGridViewDebitos.Rows(e.RowIndex).Cells(ColumnDebito.Index)
        Dim numDebito = String.Concat(If(cellDebito.Value, "").ToString.Where(Function(c) Char.IsLetterOrDigit(c)))
        If TypeOf cellDebito Is DataGridViewTextBoxCell AndAlso numDebito.Length >= 3 Then
            Dim prcsa As New List(Of JObject) 'In real version, prcsa is populated by an external function, but it doesn't affect the result
            Dim j = New JObject
            j.SetProperty("id", 0)
            j.SetProperty("nome", cellDebito.Value)
            prcsa.Insert(0, j) 'This option is always present, it allows user to keep simply what was typed
            'Exception hapens here
            DataGridViewDebitos(cellDebito.ColumnIndex, cellDebito.RowIndex) =
                New DataGridViewComboBoxCell With {
                    .DataSource = prcsa,
                    .DisplayMember = "nome",
                    .FlatStyle = FlatStyle.Flat,
                    .ValueMember = "id",
                    .Value = prcsa(0).Value(Of Integer)("id")}
        End If
    End If
End Sub

非常感谢

1 个答案:

答案 0 :(得分:0)

我通过.BeginInvoke将问题语句放入Lambda子中,这解决了问题,只是我不知道为什么......

有人可以向我解释它的机制吗?谢谢!

Private Sub DataGridViewDebitos_CellValidated(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridViewDebitos.CellValidated
    DataGridViewDebitos.EndEdit(DataGridViewDataErrorContexts.Commit)
    If e.ColumnIndex = ColumnDebito.Index Then
        Dim cellDebito = DataGridViewDebitos.Rows(e.RowIndex).Cells(ColumnDebito.Index)
        Dim numDebito = String.Concat(If(cellDebito.Value, "").ToString.Where(Function(c) Char.IsLetterOrDigit(c)))
        If TypeOf cellDebito Is DataGridViewTextBoxCell AndAlso numDebito.Length >= 3 Then
            Dim prcsa As New List(Of JObject) 'In real version, prcsa is populated by an external function, but it doesn't affect the result
            Dim j = New JObject
            j.SetProperty("id", 0)
            j.SetProperty("nome", cellDebito.Value)
            prcsa.Insert(0, j) 'This option is always present, it allows user to keep simply what was typed
            'Exception hapens here
            DataGridViewDebitos.BeginInvoke(
                Sub()
                    DataGridViewDebitos(cellDebito.ColumnIndex, cellDebito.RowIndex) =
                        New DataGridViewComboBoxCell With {
                        .DataSource = prcsa,
                        .DisplayMember = "nome",
                        .FlatStyle = FlatStyle.Flat,
                        .ValueMember = "id",
                        .Value = prcsa(0)("id")}
                End Sub)
        End If
    End If
End Sub