Установить новый 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 ответ

Решение

Я поместил проблемное утверждение в Lambda sub через.BeginInvoke, и это решило проблему, только я не знаю почему...

Кто-нибудь может объяснить мне механику этого? Спасибо!

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
Другие вопросы по тегам