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 de clic en ese 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 de clic en ese botón en DataGridView.
Respuestas:
Agregó un botón a su DataGridView
y desea ejecutar un código cuando se hace clic.
Fácil, solo sigue estos pasos:
Primero, esto es lo que NO debes hacer:
Evitaría las sugerencias en algunas de las otras respuestas aquí e incluso las que proporciona la documentación de MSDN para codificar el índice o el nombre de la columna para determinar si se hizo clic en un botón. El evento click se registra para toda la cuadrícula, por lo que de alguna manera debe determinar que se hizo clic en un botón, pero no debe hacerlo asumiendo que su botón vive 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. Nuevamente, la documentación y muchos ejemplos se equivocan. La mayoría de los ejemplos manejan el CellClick
evento que se disparará:
cuando se hace clic en cualquier parte de una celda.
... pero también se disparará cada vez que se haga clic en el encabezado de la fila . Esto requiere agregar código adicional simplemente para determinar si el e.RowIndex
valor es menor que 0
En su lugar, maneje lo 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.
Entonces, esto es lo que debes hacer:
Primero, envíe el remitente a escribir DataGridView
para exponer sus propiedades internas en tiempo de diseño. Puede modificar el tipo en el parámetro, pero eso a veces puede hacer que agregar o quitar controladores sea complicado.
A continuación, para ver si se hizo clic en un botón, solo verifique para asegurarse de que la columna que genera el evento sea de tipo DataGridViewButtonColumn
. Debido a que ya enviamos al remitente a escribir DataGridView
, podemos obtener la Columns
colección y seleccionar la columna actual usando e.ColumnIndex
. Luego verifique si ese objeto es de tipo DataGridViewButtonColumn
.
Por supuesto, si necesita distinguir entre varios botones por cuadrícula, puede seleccionar según el nombre de la columna o el índice, pero esa no debería ser su primera comprobación. Siempre asegúrese de hacer clic primero en un botón y luego maneje cualquier otra cosa de manera apropiada. En la mayoría de los casos en los que solo tiene un solo botón por cuadrícula, puede saltar directamente a las carreras.
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
Si desea divertirse un poco, puede agregar su propio evento para que se genere cada vez que se hace clic en un botón en DataGrid. No puede agregarlo a DataGrid en sí, sin desordenarse con la herencia, etc., pero puede agregar un evento personalizado a su formulario y activarlo cuando sea apropiado. 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 manejelo. 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
Lo que sería genial es si estuviéramos trabajando con una grilla que acaba de hacer estas cosas por nosotros. Podríamos responder a 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 el 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 un DataGridView. Excepto que también generará un evento adicional que puedes manejar así:
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); } } }
Eso se responde completamente aquí 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é usando realmente. (Su pregunta dice DataGrid, pero está desarrollando una aplicación de Windows, por lo que el control que usaría allí es un DataGridView ...)
dataGridView1_CellClick
ese código. ¿Puedes actualizar tu respuesta y darme una descripción?
Aquí está la mejor respuesta:
No puede implementar un evento 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
Un poco tarde para la tabla aquí, pero en c # (vs2013) tampoco necesita usar nombres de columna, 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 puesto el DataGridView). Desde el código del diseñador (las cosas que no 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;
Entonces, en el controlador CellContentClick, además de asegurarse de que el índice de la fila no sea 0, solo debe verificar si la columna en la que se hizo clic es la que desea mediante la comparación de referencias de 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á captado por el compilador. Si indexa con un nombre de texto que cambia, o que capitaliza incorrectamente, está obligado a 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 compilación le indicará el compilador.
Aquí está mi fragmento de código para activar el evento de clic y pasar el valor a otro formulario:
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();
}
}
Suponiendo, por ejemplo, que las DataGridView
columnas se muestran a continuación y que sus elementos enlazados a datos son del tipo PrimalPallet
que puede usar, la solución se proporciona a continuación.
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 columnas de acceso directamente en lugar de utilizar dataGridView1.Columns["MyColumnName"]
y no hay necesidad de analizar sender
a la DataGridView
ya que no es necesario.
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 de propietarios, nuestro método también se disparará.
En el método IClicked_MyButton_, simplemente coloca lo que quieras que suceda 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 aquí dependen de usted, pero si falta algo más conceptualmente, hágamelo saber y trataré de 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 ToList()
método al final de su lista, donde se une a datagridview DataSource:
dataGridView1.DataSource = MyList.ToList();
Puede probar este, no le importaría 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 :)
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 del todo. Notarás que Peter preguntó "¿De dónde obtendrías el botón?", Pero no recibió respuesta.
La única forma en que funcionó para mí fue hacer una de las siguientes acciones para agregar mi controlador de eventos (después de configurar DataSource de DataGridView en mi DataTable y después 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 declaración AddHandler como se describe en el documento de Microsoft " Cómo: llamar a un controlador de eventos en Visual Basic "
Agregará una columna de botón como esta en su dataGridView
DataGridViewButtonColumn mButtonColumn0 = new DataGridViewButtonColumn();
mButtonColumn0.Name = "ColumnA";
mButtonColumn0.Text = "ColumnA";
if (dataGridView.Columns["ColumnA"] == null)
{
dataGridView.Columns.Insert(2, mButtonColumn0);
}
Luego puede agregar algunas acciones dentro del evento de clic de celda. Encontré que esta es la forma más fácil de hacerlo.
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.
}
}
Descubrí que el evento Cell Click se suscribe automáticamente a menudo. Entonces no necesitaba este código a continuación. Sin embargo, si su evento de clic en la celda no está suscrito, agregue esta línea de código para su dataGridView.
this.dataGridView.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellClick);