Вы добавили кнопку в DataGridView
и хотите запустить какой-нибудь код при нажатии.
Легко peasy - просто выполните следующие действия:
Этикет:
Во-первых, вот что НЕ сделать:
Я бы не советовал в некоторых других ответах здесь и даже в документации на MSDN жестко закодировать индекс столбца или имя столбца, чтобы определить, была ли нажата кнопка. Событие click регистрируется для всей сетки, так что каким-то образом вам нужно определить, что кнопка была нажата, но вы не должны этого делать, предполагая, что ваша кнопка живет с определенным именем столбца или индексом ... есть более простой способ ...
Кроме того, будьте осторожны, какое событие вы хотите обработать. Опять же, документация и многие примеры ошибаются. Большинство примеров обрабатывают событие CellClick
, которое вызовет:
при нажатии любой части ячейки.
... но также срабатывает при каждом щелчке по заголовку row . Это требует добавления дополнительного кода, чтобы просто определить, меньше ли значение e.RowIndex
, чем 0
.
Вместо этого обработайте CellContentClick
, который происходит только:
при нажатии на содержимое в ячейке
По какой-либо причине заголовок столбца также считается «содержимым» внутри ячейки, поэтому нам все равно придется проверить это ниже.
Dos:
Итак, вот что вы должны сделать:
Сначала приведите отправителя к DataGridView
, чтобы раскрыть его внутренние свойства во время разработки. Вы можете изменить тип параметра, но иногда это может усложнить добавление или удаление обработчиков.
Далее, чтобы увидеть, была ли нажата кнопка, просто убедитесь, что столбец, вызывающий событие, имеет тип DataGridViewButtonColumn
. Поскольку мы уже приводим отправителя к типу DataGridView
, мы можем получить коллекцию Columns
и выбрать текущий столбец, используя e.ColumnIndex
. Затем проверьте, имеет ли этот объект тип DataGridViewButtonColumn
.
Конечно, если вам нужно различать несколько кнопок на сетке, вы можете выбрать на основе имени столбца или индекса, но это не должно быть вашей первой проверкой. Всегда убедитесь, что кнопка была нажата в первую очередь, а затем обрабатывать что-либо еще соответствующим образом. В большинстве случаев, когда у вас есть только одна кнопка на сетке, вы можете сразу перейти к гонкам.
Собираем все вместе:
C #
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;
if (senderGrid.Columns[e.ColumnIndex] is DataGridViewButtonColumn &&
e.RowIndex >= 0)
{
//TODO - Button Clicked - Execute Code Here
}
}
VB
Private Sub DataGridView1_CellContentClick(sender As System.Object, e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellContentClick
Dim senderGrid = DirectCast(sender, DataGridView)
If TypeOf senderGrid.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso
e.RowIndex >= 0 Then
'TODO - Button Clicked - Execute Code Here
End If
End Sub
Обновление 1 - пользовательское событие
Если вы хотите немного повеселиться, вы можете добавить свое собственное событие, которое будет вызываться при каждом нажатии кнопки в DataGrid. Вы не можете добавить его в саму DataGrid, не запутавшись в наследовании и т. Д., Но вы можете добавить пользовательское событие в свою форму и запустить его при необходимости. Это немного больше кода, но положительным моментом является то, что вы выделили то, что вы хотите делать при нажатии кнопки, и как определить, была ли нажата кнопка.
Просто объявляйте событие, вызывайте его, когда необходимо, и обрабатывайте его. Это будет выглядеть так:
Event DataGridView1ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs)
Private Sub DataGridView1_CellContentClick(sender As System.Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
Dim senderGrid = DirectCast(sender, DataGridView)
If TypeOf senderGrid.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso e.RowIndex >= 0 Then
RaiseEvent DataGridView1ButtonClick(senderGrid, e)
End If
End Sub
Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) Handles Me.DataGridView1ButtonClick
'TODO - Button Clicked - Execute Code Here
End Sub
Обновление 2 - Расширенная сетка
Что было бы здорово, если бы мы работали с сеткой, которая просто делала эти вещи для нас. Мы могли бы легко ответить на первоначальный вопрос: you've added a button to your DataGridView and you want to run some code when it's clicked
. Вот подход, который расширяет DataGridView
. Возможно, не стоит доставлять пользовательский элемент управления каждой библиотеке, но, по крайней мере, он максимально использует код, используемый для определения нажатия кнопки.
Просто добавьте это в вашу сборку:
Public Class DataGridViewExt : Inherits DataGridView
Event CellButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs)
Private Sub CellContentClicked(sender As System.Object, e As DataGridViewCellEventArgs) Handles Me.CellContentClick
If TypeOf Me.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso e.RowIndex >= 0 Then
RaiseEvent CellButtonClick(Me, e)
End If
End Sub
End Class
Вот и все. Никогда не трогай это снова. Убедитесь, что ваш DataGrid имеет тип DataGridViewExt
, который должен работать точно так же, как DataGridView. Кроме того, это также вызовет дополнительное событие, которое вы можете обработать следующим образом:
Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellButtonClick
'TODO - Button Clicked - Execute Code Here
End Sub