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