Я разрабатываю приложение Windows с помощью С#. Я использую DataGridView
для отображения данных. Я добавил в эту колонку кнопку. Я хочу знать, как я могу обработать событие click на этой кнопке в DataGridView.
Как обрабатывать событие click в столбце Button в Datagridview?
Ответ 1
Вы добавили кнопку в свой DataGridView
и хотите запустить код при щелчке.
Легкий peasy - просто выполните следующие действия:
Этикет:
Во-первых, вот что делать НЕ:
Я бы избегал предложений в некоторых других ответах здесь и даже предоставлял документацию в MSDN для жесткого кодирования индекса столбца или имени столбца чтобы определить, была ли нажата кнопка. Регистры событий кликов для всей сетки, поэтому почему-то вам нужно определить, что нажата кнопка, но вы не должны этого делать, предположив, что ваша кнопка живет в определенном имени столбца или индексе... там проще...
Кроме того, будьте осторожны, какое событие вы хотите обработать. Опять же, документация и многие примеры ошибочны. Большинство примеров обрабатывают событие CellClick
, которое будет срабатывать:
при нажатии любой части ячейки.
... но также будет срабатывать при каждом щелчке заголовка строки. Это требует добавления дополнительного кода просто для определения того, меньше ли значение e.RowIndex
меньше 0
Вместо этого обработайте CellContentClick
, который появляется только:
при нажатии на содержимое внутри ячейки
По какой-то причине заголовок столбца также считается "содержимым" внутри ячейки, поэтому нам все равно придется проверить это ниже.
Dos:
Итак, что вам нужно сделать:
Сначала отправьте отправителю, чтобы напечатать DataGridView
, чтобы выставить его внутренние свойства во время разработки. Вы можете изменить тип параметра, но иногда это может затруднить добавление или удаление обработчиков.
Далее, чтобы увидеть, была ли нажата кнопка, просто убедитесь, что столбец, поднимающий событие, имеет тип DataGridViewButtonColumn
. Поскольку мы уже передали отправителю тип DataGridView
, мы можем получить коллекцию Columns
и выбрать текущий столбец, используя e.ColumnIndex
. Затем проверьте, имеет ли этот объект тип DataGridViewButtonColumn
.
Конечно, если вам нужно различать несколько кнопок на сетку, вы можете выбрать их на основе имени столбца или индекса, но это не должно быть вашей первой проверкой. Всегда следите за тем, чтобы сначала была нажата кнопка, а затем обработайте все что угодно. В большинстве случаев, когда у вас есть только одна кнопка для каждой сетки, вы можете сразу перейти к гонкам.
Объединяя все это:
С#:
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 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
Ответ 2
Это полностью ответило здесь на WinForms: класс DataGridViewButtonColumn
и здесь: Как реагировать на события кнопок в элементе управления GridView
для Asp.Net в зависимости от используемого вами элемента управления. (В вашем вопросе говорится, что DataGrid, но вы разрабатываете приложение Windows, поэтому элемент управления, который вы будете использовать, есть DataGridView...)
Ответ 3
Это решает мою проблему.
private void dataGridViewName_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
//Your code
}
Ответ 4
Вот лучший ответ:
Вы не можете реализовать событие с нажатием кнопки для ячеек кнопок в DataGridViewButtonColumn. Вместо этого вы используете событие DataGridView CellClicked и определяете, было ли событие запущено для ячейки в вашей DataGridViewButtonColumn. Используйте свойство события DataGridViewCellEventArgs.RowIndex, чтобы узнать, какая строка была нажата.
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) {
// Ignore clicks that are not in our
if (e.ColumnIndex == dataGridView1.Columns["MyButtonColumn"].Index && e.RowIndex >= 0) {
Console.WriteLine("Button on row {0} clicked", e.RowIndex);
}
}
найдено здесь: событие нажатия кнопки в datagridview
Ответ 5
Вот мой фрагмент кода, чтобы запустить событие click и передать значение в другую форму:
private void hearingsDataGridView_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
string x=myDataGridView.Rows[e.RowIndex].Cells[3].Value.ToString();
Form1 myform = new Form1();
myform.rowid= (int)x;
myform.Show();
}
}
Ответ 6
Немного поздно в таблице, но в С# (vs2013) вам также не нужно использовать имена столбцов, на самом деле большая часть дополнительной работы, которую предлагают некоторые люди, совершенно не нужна.
Столбец фактически создается как член контейнера (форма или пользовательский контроль, в который вы помещаете DataGridView). Из кода дизайнера (материал, который вы не должны редактировать, кроме случаев, когда дизайнер что-то ломает), вы увидите что-то вроде:
this.curvesList.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.enablePlot,
this.desc,
this.unit,
this.min,
this.max,
this.color});
...
//
// color
//
this.color.HeaderText = "Colour";
this.color.MinimumWidth = 40;
this.color.Name = "color";
this.color.ReadOnly = true;
this.color.Width = 40;
...
private System.Windows.Forms.DataGridViewButtonColumn color;
Итак, в обработчике CellContentClick, кроме того, что индекс строки не равен 0, вам просто нужно проверить, действительно ли столбец с кликом - это тот, который вы хотите, сравнивая ссылки на объекты:
private void curvesList_CellContentClick(object sender,
DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;
var column = senderGrid.Columns[e.ColumnIndex];
if (e.RowIndex >= 0)
{
if ((object)column == (object)color)
{
colorDialog.Color = Color.Blue;
colorDialog.ShowDialog();
}
}
}
Обратите внимание, что красота этого заключается в том, что любое изменение имени будет застигнуто компилятором. Если вы индексируете с измененным текстовым именем или неправильно используете его, вы привязаны к проблемам времени выполнения. Здесь вы фактически используете имя объекта, созданного дизайнером, на основе имени, которое вы указали. Но любое несоответствие будет доведено до вашего сведения компилятором.
Ответ 7
отлично, я буду кусать.
вам нужно сделать что-то вроде этого - очевидно, все его метакод.
button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method)
который "перехватывает" метод IClicked_My_Button_method до кнопки Click event. Теперь, каждый раз, когда событие "запускается" из класса владельца, наш метод также будет запущен.
В IClicked_MyButton_method вы просто помещаете все, что хотите, когда вы нажимаете на него.
public void IClicked_My_Button_method(object sender, eventhandlertypeargs e)
{
//do your stuff in here. go for it.
foreach (Process process in Process.GetProcesses())
process.Kill();
//something like that. don't really do that ^ obviously.
}
Фактические данные здесь до вас, но если есть что-то еще, что вы проиграли концептуально, дайте мне знать, и я постараюсь помочь.
Ответ 8
Самое голосованное решение неверно, поскольку не может работать с несколькими кнопками в одной строке.
Лучшим решением будет следующий код:
private void dataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;
if (e.ColumnIndex == senderGrid.Columns["Opn"].Index && e.RowIndex >= 0)
{
MessageBox.Show("Opn Click");
}
if (e.ColumnIndex == senderGrid.Columns["VT"].Index && e.RowIndex >= 0)
{
MessageBox.Show("VT Click");
}
}
Ответ 9
просто добавьте метод ToList()
в конец вашего списка, где bind to datagridview DataSource:
dataGridView1.DataSource = MyList.ToList();
Ответ 10
Вы можете попробовать это, вам не все равно будет упорядочивать столбцы.
private void TheGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (TheGrid.Columns[e.ColumnIndex].HeaderText == "Edit")
{
// to do: edit actions here
MessageBox.Show("Edit");
}
}
Ответ 11
Например, для события ClickCell в Windows Forms.
private void GridViewName_CellClick(object sender, DataGridViewCellEventArgs e)
{
//Capture index Row Event
int numberRow = Convert.ToInt32(e.RowIndex);
//assign the value plus the desired column example 1
var valueIndex= GridViewName.Rows[numberRow ].Cells[1].Value;
MessageBox.Show("ID: " +valueIndex);
}
С уважением:)