Как обрабатывать событие щелчка мышью в колонке кнопки управления datagridview?


Я разрабатываю приложение для windows с помощью C#. Я использую DataGridView для отображения данных. Я добавил столбец кнопки в этом. Я хочу знать, как я могу обрабатывать событие click на этой кнопке в DataGridView.

13 107

13 ответов:

вы добавили кнопку DataGridView и вы хотите запустить какой-то код, когда он щелкнул.
Все просто - просто выполните следующие действия:

минусы:

во-первых, вот что не чтобы делать:

я бы избегал предложений в некоторых других ответах здесь и даже предоставленных документация на MSDN чтобы жестко закодировать индекс столбца или имя столбца, чтобы определить, была ли нажата кнопка. Событие click регистры для всей сетки, поэтому каким-то образом вам нужно определить, что кнопка была нажата, но вы не должны этого делать, предполагая, что ваша кнопка живет в определенном имени столбца или индексе... есть более простой способ...

кроме того, будьте осторожны, какое событие вы хотите обрабатывать. Опять же, документация и многие примеры ошибаются. Большинство примеров обрабатывают CellClick событие, которое будет срабатывать:

когда любая часть клетки нажатый.

...но также будет стрелять всякий раз, когда row кнопки. Это требует добавления дополнительного кода, чтобы просто определить, если e.RowIndex значение меньше 0

вместо того чтобы обрабатывать CellContentClick, который происходит только:

когда содержимое в ячейке нажата

по какой причине колонки заголовок также считается "содержимым" в ячейке, поэтому нам все равно придется проверить это ниже.

Dos:

Итак, вот что вы должны сделать:

первый, cast отправитель для ввода 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
    }
}

В. Б.:

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

Это ответ полностью здесь для WinForms: DataGridViewButtonColumn Class

и здесь: как реагировать на события кнопок в элементе управления GridView

для Asp.Net в зависимости от контроля, который вы на самом деле используете. (Ваш вопрос говорит DataGrid, но вы разрабатываете приложение для Windows, поэтому элемент управления, который вы будете использовать, - это DataGridView...)

вот лучший ответ:

вы не можете реализовать событие нажатия кнопки для ячеек кнопки в 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

Это решает мою проблему.

private void dataGridViewName_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        //Your code
    }

немного поздно для таблицы здесь, но в c# (vs2013) вам также не нужно использовать имена столбцов, на самом деле много дополнительной работы, которую предлагают некоторые люди, совершенно не нужно.

столбец фактически создается как член контейнера (форма или usercontrol, в который вы поместили 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 вы можете использовать решение, приведенное ниже.

enter image description here

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 до события нажатия кнопки. Теперь каждый раз, когда событие "запускается" из класса владельца, наш метод также будет запущен.

в 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 ниже) и достиг этой точки, но все еще застрял, пожалуйста, читайте дальше.

единственный способ, которым это сработало для меня, - это сделать одно из следующих действий, чтобы добавить мой обработчик событий (после установки источника данных моего 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 Основные"