vb.netwinformsdatagridviewdatagridviewcomboboxcelldatagridviewtextboxcell

set new DataGridViewComboBoxCell for after validation of previous DataGridViewTextBoxCell in same column and row


I have this DataGridView and it has a DataGridViewTextBoxColumn where user can type a number, and after he types it I perform a search to find previous records under that number.

I want to show this records so user can select one of them, or keep the value typed, which means he wants to create a new record.

For that, I want to replace each DataGridViewTextBoxCell for a DataGridViewComboBoxCell with those options when user has finished typing.

However, it is raising this exception when I try to permform this replacement: "System.InvalidOperationException" in System.Windows.Forms.dll. Additional information: The operation is not valid because it results in a reentering call to the function SetCurrentCellAddressCore.

Here is my code (I already tried to handle CellLeave instead of 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

Thank you very much


Solution

  • I've put the problematic statement into a Lambda sub via .BeginInvoke and this solved the problem, only I don't know why...

    Can anyone explain the mechanics of it to me? Thank you!

    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