¿Cómo manejar el evento de clic en la columna de botón en Datagridview?

Estoy desarrollando una aplicación de Windows usando C #. Estoy usando DataGridView para mostrar datos. He agregado una columna de botón en eso. Quiero saber cómo puedo manejar el evento click en ese botón en DataGridView.

Ha agregado un botón a su DataGridView y desea ejecutar algún código cuando se hace clic.
Easy peasy – solo sigue estos pasos:

Qué no hacer:

Primero, esto es lo que NO debes hacer:

Evitaría las sugerencias en algunas de las otras respuestas aquí e incluso las proporcionadas por la documentación en MSDN para codificar el índice de la columna o el nombre de la columna para determinar si se hizo clic en un botón. El evento de clic se registra para toda la grilla, por lo que de alguna manera debe determinar que se hizo clic en un botón, pero no debe hacerlo suponiendo que su botón se encuentre en un nombre o índice de columna en particular … hay una manera más fácil …

Además, tenga cuidado con el evento que desea manejar. De nuevo, la documentación y muchos ejemplos lo malinterpretan. La mayoría de los ejemplos manejan el evento CellClick que se activará:

cuando se hace clic en cualquier parte de una celda.

… pero también se activará cada vez que se haga clic en el encabezado de la fila . Esto requiere agregar código adicional simplemente para determinar si el valor de e.RowIndex es menor que 0

En su lugar, maneje el CellContentClick que solo ocurre:

cuando se hace clic en el contenido dentro de una celda

Por alguna razón, el encabezado de la columna también se considera ‘contenido’ dentro de una celda, por lo que aún tendremos que verificarlo a continuación.

Dos:

Entonces, esto es lo que debes hacer:

Primero, envíe al remitente a escribir DataGridView para exponer sus propiedades internas en el momento del diseño. Puede modificar el tipo en el parámetro, pero a veces puede hacer que agregar o quitar manejadores sea complicado.

A continuación, para ver si se hizo clic en un botón, simplemente verifique que la columna que genera el evento sea de tipo DataGridViewButtonColumn . Debido a que ya seleccionamos al emisor para que escriba DataGridView , podemos obtener la colección Columns y seleccionar la columna actual utilizando e.ColumnIndex . Luego verifique si ese objeto es de tipo DataGridViewButtonColumn .

Por supuesto, si necesita distinguir entre varios botones por cuadrícula, puede seleccionar basándose en el nombre o índice de la columna, pero esa no debería ser su primera verificación. Siempre asegúrese de hacer clic primero en un botón y luego maneje cualquier otra cosa apropiadamente. En la mayoría de los casos en que solo tienes un botón por cuadrícula, puedes saltar directamente a las carreras.

Poniendolo todo junto:

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 

Actualización 1 – Evento personalizado

Si desea divertirse un poco, puede agregar su propio evento para que se muestre siempre que se haga clic en un botón en DataGrid. No puede agregarlo al DataGrid mismo, sin ensuciarse con la herencia, etc., pero puede agregar un evento personalizado a su formulario y activarlo cuando corresponda. Es un poco más de código, pero lo bueno es que ha separado lo que quiere hacer cuando se hace clic en un botón con la forma de determinar si se hizo clic en un botón.

Simplemente declare un evento, críelo cuando sea apropiado y manipúlelo. Se verá así:

 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 

Actualización 2: cuadrícula extendida

Lo que sería genial es si estuviéramos trabajando con una grilla que solo hizo estas cosas por nosotros. Podríamos responder la pregunta inicial fácilmente: you've added a button to your DataGridView and you want to run some code when it's clicked . Aquí hay un enfoque que extiende DataGridView . Puede que no valga la pena tener que entregar un control personalizado con cada biblioteca, pero al menos reutiliza al máximo el código utilizado para determinar si se hizo clic en un botón.

Simplemente agregue esto a su ensamblaje:

 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 

Eso es. Nunca lo toques de nuevo. Asegúrese de que su DataGrid sea del tipo DataGridViewExt que debería funcionar exactamente igual que DataGridView. Excepto que también generará un evento extra que puedes manejar de esta manera:

 Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) _ Handles DataGridView1.CellButtonClick 'TODO - Button Clicked - Execute Code Here End Sub 

Aquí se responde completamente para WinForms: DataGridViewButtonColumn Class

y aquí: Cómo responder a eventos de botón en un control GridView

para Asp.Net dependiendo del control que estás usando en realidad. (Su pregunta dice DataGrid, pero está desarrollando una aplicación de Windows, por lo que el control que usaría allí es un DataGridView …)

Aquí está la mejor respuesta:

No puede implementar un evento de clic de botón para celdas de botón en un DataGridViewButtonColumn. En su lugar, utiliza el evento CellClicked de DataGridView y determina si el evento se activó para una celda en su DataGridViewButtonColumn. Use la propiedad DataGridViewCellEventArgs.RowIndex del evento para averiguar en qué fila se hizo clic.

 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); } } 

encontrado aquí: evento de clic de botón en datagridview

Esto resuelve mi problema.

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

Llegamos un poco tarde a la mesa, pero en c # (vs2013) tampoco necesita usar nombres de columnas, de hecho, gran parte del trabajo adicional que algunas personas proponen es completamente innecesario.

La columna se crea realmente como un miembro del contenedor (el formulario o control de usuario en el que ha insertado DataGridView). Desde el código del diseñador (las cosas que no se supone que debes editar, excepto cuando el diseñador rompe algo), verías algo como:

 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; 

Por lo tanto, en el controlador CellContentClick, además de garantizar que el índice de la fila no sea 0, solo necesita comprobar si la columna en la que hizo clic es, de hecho, la que desea al comparar las referencias de los objetos:

 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(); } } } 

Tenga en cuenta que la belleza de esto es que cualquier cambio de nombre será capturado por el comstackdor. Si indicas con un nombre de texto que cambia, o que capitalizas incorrectamente, estás obligado a los problemas de tiempo de ejecución. Aquí realmente usa el nombre de un objeto, que el diseñador crea en función del nombre que proporcionó. Pero cualquier desajuste será señalado por el comstackdor.

Aquí está mi fragmento de código para activar el evento click y pasar el valor a otra forma:

 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(); } } 

bien, voy a morder.

tendrás que hacer algo como esto, obviamente es todo metacódigo.

 button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method) 

que “engancha” el método IClicked_My_Button_method hasta el evento Click del botón. Ahora, cada vez que el evento se “dispara” desde la clase propietaria, nuestro método también se activará.

En el método IClicked_MyButton_, simplemente coloca lo que quieras que ocurra al hacer clic en él.

 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. } 

Los detalles reales dependen de usted, pero si hay algo más que le falta conceptualmente, hágamelo saber e intentaré ayudarlo.

La solución más votada es incorrecta, ya que no puede funcionar con pocos botones en una fila.

La mejor solución será el siguiente código:

 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"); } } 

simplemente agregue el método ToList() al final de su lista, donde se une a datagridview DataSource:

 dataGridView1.DataSource = MyList.ToList(); 

Puedes probar este, no te importará mucho el orden de las columnas.

 private void TheGrid_CellContentClick(object sender, DataGridViewCellEventArgs e) { if (TheGrid.Columns[e.ColumnIndex].HeaderText == "Edit") { // to do: edit actions here MessageBox.Show("Edit"); } } 

Por ejemplo, para ClickCell Event en 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); } 

Saludos 🙂

Suponiendo, por ejemplo, que DataGridView tiene columnas como se indica a continuación y que sus elementos vinculados a datos son de tipo PrimalPallet , puede usar la solución que se proporciona a continuación.

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. } } } 

Es más seguro acceder directamente a las columnas en lugar de usar dataGridView1.Columns["MyColumnName"] y no es necesario analizar el sender a DataGridView ya que no es necesario.

En caso de que alguien esté usando C # (o vea la Nota sobre VB.NET a continuación) y haya llegado a este punto, pero todavía está atascado, siga leyendo.

La respuesta de Joshua me ayudó, pero no todo el camino. Notarás que Peter preguntó “¿De dónde sacaste el botón?”, Pero no recibió respuesta.

La única forma en que funcionó fue hacer una de las siguientes acciones para agregar mi evento (después de configurar DataGridView’s DataSource en mi DataTable y luego de agregar DataGridViewButtonColumn a DataGridView):

Ya sea:

 dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick); 

o:

 dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick); 

Y luego agregue el método del controlador (ya sea dataGridView1_CellClick o dataGridView1_CellContentClick) que se muestra en las diversas respuestas anteriores.

Nota: VB.NET es diferente de C # a este respecto, porque simplemente podemos agregar una cláusula Handles a la firma de nuestro método o emitir una instrucción AddHandler como se describe en el documento de Microsoft ” Cómo: Llamar a un controlador de eventos en Visual Basic ”