Я разрабатываю приложение для Windows, используя C #. Я использую DataGridView
для отображения данных. Я добавил столбец кнопки в этом. Я хочу знать, как я могу обработать событие нажатия на эту кнопку в DataGridView.
Я разрабатываю приложение для Windows, используя C #. Я использую DataGridView
для отображения данных. Я добавил столбец кнопки в этом. Я хочу знать, как я могу обработать событие нажатия на эту кнопку в DataGridView.
Ответы:
Вы добавили кнопку к своей DataGridView
и хотите запускать некоторый код при нажатии.
Легко peasy - просто выполните следующие действия:
Во-первых, вот что НЕ нужно делать:
Я бы избегал предложений, содержащихся в некоторых других ответах здесь и даже в документации MSDN, жестко закодировать индекс столбца или имя столбца, чтобы определить, была ли нажата кнопка. Событие click регистрируется для всей сетки, поэтому каким-то образом вам нужно определить, что кнопка была нажата, но вы не должны этого делать, предполагая, что ваша кнопка живет с определенным именем столбца или индексом ... есть более простой способ ...
Кроме того, будьте осторожны, какое событие вы хотите обработать. Опять же, документация и многие примеры ошибаются. Большинство примеров обрабатывают CellClick
событие, которое сработает:
когда любая часть ячейки нажата.
... но также срабатывает при каждом щелчке по заголовку строки . Это требует добавления дополнительного кода просто для определения, если e.RowIndex
значение меньше 0
Вместо этого обработайте CellContentClick
только то, что происходит:
когда щелкается контент внутри ячейки
По какой-либо причине заголовок столбца также считается «содержимым» в ячейке, поэтому нам все еще придется проверить это ниже.
Итак, вот что вы должны сделать:
Сначала приведите отправителя к типу, 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
Если вы хотите немного повеселиться, вы можете добавить свое собственное событие, которое будет вызываться при каждом нажатии кнопки в 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
Что было бы здорово, если бы мы работали с сеткой, которая только что сделала это для нас. Мы могли бы ответить на первый вопрос легко: 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
TypeOf senderGrid.Rows(e.RowIndex).Cells(e.ColumnIndex) Is DataGridViewButtonCell
public class DataGridViewExt : DataGridView { public event DataGridViewCellEventHandler CellButtonClick; public DataGridViewExt() { this.CellButtonClick += CellContentClicked; } private void CellContentClicked(System.Object sender, DataGridViewCellEventArgs e) { if (this.Columns[e.ColumnIndex].GetType() == typeof(DataGridViewButtonColumn) && e.RowIndex >= 0 ) { CellButtonClick.Invoke(this, e); } } }
Это полностью отвечено здесь для WinForms: DataGridViewButtonColumn Class
и здесь: Как: реагировать на события кнопок в элементе управления GridView
для Asp.Net в зависимости от элемента управления, который вы на самом деле используете. (Ваш вопрос говорит о DataGrid, но вы разрабатываете приложение для Windows, поэтому используемый вами элемент управления - это DataGridView ...)
dataGridView1_CellClick
в этот код. Можете ли вы обновить свой ответ и дать мне некоторое описание.
Вот лучший ответ:
Вы не можете реализовать событие нажатия кнопки для ячеек кнопки в DataGridViewButtonColumn. Вместо этого вы используете событие CellClicked объекта DataGridView и определяете, произошло ли событие для ячейки в вашем 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
Немного опоздал к таблице здесь, но в c # (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();
}
}
}
Обратите внимание, что прелесть этого в том, что любые изменения имени будут отслеживаться компилятором. Если вы индексируете текстовое имя, которое изменяется или неправильно пишется с заглавной буквы, вы столкнетесь с проблемами во время выполнения. Здесь вы фактически используете имя объекта, который дизайнер создает на основе предоставленного вами имени. Но любое несоответствие будет доведено до вашего сведения компилятором.
Вот мой фрагмент кода для запуска события 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();
}
}
Предположим, например, DataGridView
что столбцы, как указано ниже, и его элементы данных связаны с типом, который PrimalPallet
вы можете использовать решение, приведенное ниже.
private void dataGridView1_CellContentClick( object sender, DataGridViewCellEventArgs e )
{
if ( e.RowIndex >= 0 )
{
if ( e.ColumnIndex == this.colDelete.Index )
{
var pallet = this.dataGridView1.Rows[ e.RowIndex ].DataBoundItem as PrimalPallet;
this.DeletePalletByID( pallet.ID );
}
else if ( e.ColumnIndex == this.colEdit.Index )
{
var pallet = this.dataGridView1.Rows[ e.RowIndex ].DataBoundItem as PrimalPallet;
// etc.
}
}
}
Безопаснее получать доступ к столбцам напрямую, чем к использованию, dataGridView1.Columns["MyColumnName"]
и нет необходимости анализировать sender
их, так DataGridView
как они не нужны.
хорошо, я укушу
вам нужно сделать что-то вроде этого - очевидно, все это метакод.
button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method)
это «подключает» метод IClicked_My_Button_method к событию Click кнопки. Теперь каждый раз, когда событие «запускается» из класса владельца, наш метод также запускается.
В 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.
}
Фактические детали здесь до вас, но если есть что-то еще, что вы упускаете концептуально, дайте мне знать, и я постараюсь помочь.
Решение с большинством голосов неверно, так как не может работать с несколькими кнопками в одном ряду.
Лучшим решением будет следующий код:
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");
}
}
просто добавьте ToList()
метод в конец списка, где привязка к источнику данных datagridview:
dataGridView1.DataSource = MyList.ToList();
Вы можете попробовать это, вы не будете заботиться о порядке столбцов.
private void TheGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (TheGrid.Columns[e.ColumnIndex].HeaderText == "Edit")
{
// to do: edit actions here
MessageBox.Show("Edit");
}
}
Например, для события 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);
}
С уважением :)
Если кто-то использует C # (или см. Примечание о VB.NET ниже) и достиг этой точки, но все еще застрял, пожалуйста, продолжайте читать.
Ответ Джошуа помог мне, но не до конца. Вы заметите, что Питер спросил «Откуда ты взял бы кнопку?», Но остался без ответа.
Единственный способ, которым он работал для меня, это сделать одно из следующего, чтобы добавить обработчик событий (после установки DataSridView моего DataGridView в мой DataTable и после добавления DataGridViewButtonColumn в DataGridView):
Либо:
dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);
или:
dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);
Затем добавьте метод-обработчик (dataGridView1_CellClick или dataGridView1_CellContentClick), показанный в различных ответах выше.
Примечание. В этом отношении VB.NET отличается от C # тем, что мы можем просто добавить предложение Handles к сигнатуре нашего метода или выполнить инструкцию AddHandler, как описано в документе Microsoft « Как: вызвать обработчик событий в Visual Basic »
Вы добавите столбец кнопки, как это в вашем dataGridView
DataGridViewButtonColumn mButtonColumn0 = new DataGridViewButtonColumn();
mButtonColumn0.Name = "ColumnA";
mButtonColumn0.Text = "ColumnA";
if (dataGridView.Columns["ColumnA"] == null)
{
dataGridView.Columns.Insert(2, mButtonColumn0);
}
Затем вы можете добавить некоторые действия в событие клика ячейки. Я обнаружил, что это самый простой способ сделать это.
private void dataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
{
int rowIndex = e.RowIndex;
int columnIndex = e.ColumnIndex;
if (dataGridView.Rows[rowIndex].Cells[columnIndex].Selected == true && dataGridView.Columns[columnIndex].Name == "ColumnA")
{
//.... do any thing here.
}
}
Я обнаружил, что событие Cell Click автоматически подписывается часто. Поэтому мне не нужен этот код ниже. Однако, если ваше событие клика на ячейку не подписано, добавьте эту строку кода для вашего dataGridView.
this.dataGridView.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellClick);