#c# #vb.net #events #datagridview #cell
#c# #vb.net #Мероприятия #datagridview #ячейка
Вопрос:
Я создаю бухгалтерское приложение, и у меня возникла небольшая проблема. Мне нужно, чтобы мой datagridview производил необходимые вычисления в ячейках во время записи в ячейку, а не после нажатия клавиши или выполнения любого другого типа проверки… потому что пользователь может забыть это сделать.
Итак, у меня есть это, и мой вопрос в том, какое событие я должен использовать для проверки ячейки dgw при вводе в нее? Или есть другой способ сделать это?
Private Sub NRCD_produseDataGridView_CellValueChanged(ByVal sender As Object, ByVal e
As System.Windows.Forms.Da-taGridViewCellEventArgs)
Handles NRCD_produseDataGridView.???????
// doesn't matter what is here
End Sub
Спасибо
Ответ №1:
Как вы заметили, событие CellValueChanged не подходит для этой ситуации. Почему? Поскольку значение элемента управления edit еще не перенесено обратно в DataGridView. Событие, которое вы ищете, — это EditingControlShowing. Это даст вам возможность добавлять дескрипторы к фактическому элементу управления редактированием (текстовому полю, выпадающему списку и т.д.), отображаемому в ячейке DataGridViewCell при редактировании. Обратите внимание, что когда ячейка не находится в режиме редактирования, ячейка является просто «изображением» элемента управления редактированием, нарисованного сеткой, это не фактический элемент управления.
Задавая вопрос, связанный с DataGridView, важно поделиться следующим:
- Привязана ли сетка к источнику данных?
- Если да, то каков тип базового источника данных?
- Вы запускаете сетку в виртуальном режиме?
Теперь, поскольку вы не предоставили общий доступ ни к чему из этого, в следующем примере формы предполагается, что сетка:
- Привязан к DataTable.
- Запуск в обычном режиме.
Public Class Form1
Public Sub New()
Me.InitializeComponent()
Me.ClientSize = New Size(500, 300)
Me.table = New DataTable()
Me.table.Columns.Add("Text", GetType(String))
Me.table.Columns.Add("Length", GetType(Integer))
Me.table.Rows.Add("apple", 5)
Me.table.Rows.Add("banana", 6)
Me.table.Rows.Add("orange", 6)
Me.textColumn = New DataGridViewTextBoxColumn() With {.DataPropertyName = "Text", .HeaderText = "Text", .AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill}
Me.lengthColumn = New DataGridViewTextBoxColumn() With {.DataPropertyName = "Length", .ReadOnly = True, .HeaderText = "Length (Computed)", .Width = 200, .MinimumWidth = 200}
Me.grid = New DataGridView() With {.Dock = DockStyle.Fill, .AutoGenerateColumns = False, .DataSource = Me.table}
Me.grid.Columns.AddRange({Me.textColumn, Me.lengthColumn})
Me.Controls.Add(Me.grid)
End Sub
Private Sub HandleEcShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles grid.EditingControlShowing
If (Me.grid.CurrentCell.ColumnIndex = Me.textColumn.Index) Then
Dim ec As DataGridViewTextBoxEditingControl = DirectCast(e.Control, DataGridViewTextBoxEditingControl)
Me.UnhookEc(ec) 'Important: Remove handles to avoid recursion.
Me.HookEc(ec)
End If
End Sub
Private Sub HandleEcTextChanged(sender As Object, e As EventArgs)
Dim ec As DataGridViewTextBoxEditingControl = DirectCast(sender, DataGridViewTextBoxEditingControl)
Dim cell As DataGridViewTextBoxCell = DirectCast(Me.grid.CurrentCell, DataGridViewTextBoxCell)
Me.grid.Rows(cell.RowIndex).Cells(Me.lengthColumn.Index).Value = ec.Text.Length
End Sub
Private Sub HandleEcDisposed(sender As Object, e As EventArgs)
Me.UnhookEc(TryCast(sender, DataGridViewTextBoxEditingControl)) 'Important: This will ensure removal of the hooked handles.
End Sub
Private Sub HookEc(ec As DataGridViewTextBoxEditingControl)
If (Not ec Is Nothing) Then
AddHandler ec.TextChanged, AddressOf Me.HandleEcTextChanged
AddHandler ec.Disposed, AddressOf Me.HandleEcDisposed
End If
End Sub
Private Sub UnhookEc(ec As DataGridViewTextBoxEditingControl)
If (Not ec Is Nothing) Then
RemoveHandler ec.TextChanged, AddressOf Me.HandleEcTextChanged
RemoveHandler ec.Disposed, AddressOf Me.HandleEcDisposed
End If
End Sub
Private WithEvents table As DataTable
Private WithEvents grid As DataGridView
Private WithEvents textColumn As DataGridViewTextBoxColumn
Private WithEvents lengthColumn As DataGridViewTextBoxColumn
End Class
Комментарии:
1. Привет! Извините за задержку. Я пробовал редактировать Controlshowing, но это мне не помогло. Это действовало как событие нажатия клавиши, вот почему я спросил. Данные привязаны к базе данных access, но я использовал ее только для хранения своих значений (потому что мне не удалось установить связи между таблицами и хорошо работать). В любом случае, я не очень разбираюсь в программировании, и вы сказали что-то о виртуальном / обычном режиме. Можете ли вы сказать мне, в чем разница? Это когда я нажимаю кнопку отладки, а не при использовании приложения на другом компьютере?? Спасибо
Ответ №2:
Я изменил код и добавил текстовое поле.
Если изменена, например, первая ячейка, то я нажимаю на текстовое поле и снова нажимаю на измененную ячейку, чтобы повторить попытку записи в ту же ячейку, редкий эффект и неправильно записывается в ту же ячейку. Вам нужно изменить строку и вернуться к предыдущей ячейке, чтобы выполнить обратную запись в этой ячейке.
Я заинтересован в том, чтобы код работал таким образом, но это не создает такого странного эффекта.
Если я удалю следующую строку кода в событии HandleEcTextChanged (…)
Я.сетка.Строки (ячейка.RowIndex) .Cells (Me.lengthColumn.Индекс) .Значение = ec.Text.Length
проблема не возникает, но мне нужно программно обновить столбец длины.
Кроме того, если datagridview подключен к базе данных, вы получаете сообщение об ошибке «Поврежден индекс объекта datatable».
Шаги по воспроизведению проблемы:
- Измените первую ячейку datagridview «apple».
- Нажмите текстовое поле «0000000».
- Щелкните на ячейке, измененной выше.
- Введите любое значение в текущую ячейку.
- В предыдущем пункте возникает проблема. Неправильно записывается в ячейку.
Пожалуйста, помогите.
Спасибо.
Public Class TextBoxDirectCast
Private WithEvents table As DataTable
Private WithEvents grid As DataGridView
Private WithEvents textColumn As DataGridViewTextBoxColumn
Private WithEvents lengthColumn As DataGridViewTextBoxColumn
Private WithEvents texboxtext As TextBox
Public Sub New()
Me.InitializeComponent()
Me.ClientSize = New Size(400, 300)
Me.table = New DataTable()
Me.table.Columns.Add("Text", GetType(String))
Me.table.Columns.Add("Length", GetType(Integer))
Me.table.Rows.Add("apple", 5)
Me.table.Rows.Add("banana", 6)
Me.table.Rows.Add("orange", 6)
Me.textColumn = New DataGridViewTextBoxColumn() With {.DataPropertyName = "Text", .HeaderText = "Text", .AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill}
Me.lengthColumn = New DataGridViewTextBoxColumn() With {.DataPropertyName = "Length", .ReadOnly = True, .HeaderText = "Length (Computed)", .Width = 200, .MinimumWidth = 200}
Me.grid = New DataGridView() With {.Dock = DockStyle.Top, .AutoGenerateColumns = False, .DataSource = Me.table, .TabIndex = 0}
Me.grid.Columns.AddRange({Me.textColumn, Me.lengthColumn})
Me.Controls.Add(Me.grid)
Me.texboxtext = New TextBox With {.Anchor = AnchorStyles.Bottom Or AnchorStyles.Left, .Text = "0000000", .Location = New Point(10, Me.ClientSize.Height - 30), .TabIndex = 1}
Me.Controls.Add(Me.texboxtext)
Me.texboxtext.BringToFront()
End Sub
Private Sub HandleEcShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles grid.EditingControlShowing
If (Me.grid.CurrentCell.ColumnIndex = Me.textColumn.Index) Then
Dim ec As DataGridViewTextBoxEditingControl = DirectCast(e.Control, DataGridViewTextBoxEditingControl)
Me.UnhookEc(ec) 'Important: Remove handles to avoid recursion.
Me.HookEc(ec)
End If
End Sub
Private Sub HandleEcTextChanged(sender As Object, e As EventArgs)
Dim ec As DataGridViewTextBoxEditingControl = DirectCast(sender, DataGridViewTextBoxEditingControl)
Dim cell As DataGridViewTextBoxCell = DirectCast(Me.grid.CurrentCell, DataGridViewTextBoxCell)
Me.grid.Rows(cell.RowIndex).Cells(Me.lengthColumn.Index).Value = ec.Text.Length
End Sub
Private Sub HandleEcDisposed(sender As Object, e As EventArgs)
Me.UnhookEc(TryCast(sender, DataGridViewTextBoxEditingControl)) 'Important: This will ensure removal of the hooked handles.
End Sub
Private Sub HookEc(ec As DataGridViewTextBoxEditingControl)
If (Not ec Is Nothing) Then
AddHandler ec.TextChanged, AddressOf Me.HandleEcTextChanged
AddHandler ec.Disposed, AddressOf Me.HandleEcDisposed
End If
End Sub
Private Sub UnhookEc(ec As DataGridViewTextBoxEditingControl)
If (Not ec Is Nothing) Then
RemoveHandler ec.TextChanged, AddressOf Me.HandleEcTextChanged
RemoveHandler ec.Disposed, AddressOf Me.HandleEcDisposed
End If
End Sub
End Class
Комментарии:
1. Помогите с этим, пожалуйста, танки