Comment gérer l’événement click dans la colonne Button dans Datagridview?

Je développe une application Windows en utilisant C #. J’utilise DataGridView pour afficher des données. J’ai ajouté une colonne de boutons à cela. Je veux savoir comment gérer l’événement click sur ce bouton dans DataGridView.

Vous avez ajouté un bouton à votre DataGridView et vous souhaitez exécuter du code lorsqu’il est cliqué.
Easy Peasy – suivez ces étapes:

À ne pas faire:

Tout d’abord, voici ce qu’il ne faut pas faire:

Je voudrais éviter les suggestions dans certaines des autres réponses ici et même fournies par la documentation de MSDN pour coder en dur l’index de colonne ou le nom de colonne afin de déterminer si un bouton a été cliqué. L’événement click s’enregistre pour l’ensemble de la grid, vous devez donc déterminer si un bouton a été cliqué, mais vous ne devriez pas le faire en supposant que votre bouton se trouve dans un nom ou un index de colonne particulier …

Faites également attention à l’événement que vous voulez gérer. Encore une fois, la documentation et de nombreux exemples se trompent. La plupart des exemples traitent de l’événement CellClick qui déclenchera:

lorsqu’une partie d’une cellule est cliquée.

… mais déclenche également chaque fois que vous cliquez sur l’en-tête de la ligne . Cela nécessite d’append du code supplémentaire simplement pour déterminer si la valeur e.RowIndex est inférieure à 0

Au lieu de cela, manipulez le CellContentClick qui se produit uniquement:

lorsque le contenu d’une cellule est cliqué

Pour une raison quelconque, l’en tête de colonne est également considéré comme un «contenu» dans une cellule. Nous devons donc toujours vérifier cela.

Dos:

Alors, voici ce que vous devriez faire:

Tout d’abord, lancez l’expéditeur pour saisir DataGridView afin d’exposer ses propriétés internes au moment du design. Vous pouvez modifier le type sur le paramètre, mais cela peut parfois compliquer l’ajout ou la suppression de gestionnaires.

Ensuite, pour voir si un bouton a été cliqué, vérifiez simplement que la colonne générant l’événement est de type DataGridViewButtonColumn . Étant donné que nous avons déjà lancé l’expéditeur pour saisir DataGridView , nous pouvons obtenir la collection Columns et sélectionner la colonne en e.ColumnIndex aide de e.ColumnIndex . Vérifiez ensuite si cet object est de type DataGridViewButtonColumn .

Bien sûr, si vous devez distinguer plusieurs boutons par grid, vous pouvez sélectionner le nom ou l’index de la colonne, mais cela ne devrait pas être votre première vérification. Assurez-vous toujours qu’un bouton a été cliqué en premier, puis manipulez tout ce qui est approprié. Dans la plupart des cas où vous ne disposez que d’un seul bouton par grid, vous pouvez passer directement aux courses.

Mettre tous ensemble:

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 

Mise à jour 1 – Événement personnalisé

Si vous voulez vous amuser un peu, vous pouvez append votre propre événement à déclencher chaque fois qu’un bouton est cliqué sur le DataGrid. Vous ne pouvez pas l’append au DataGrid lui-même, sans vous tracasser avec l’inheritance, etc., mais vous pouvez append un événement personnalisé à votre formulaire et le déclencher, le cas échéant. C’est un peu plus de code, mais l’avantage est que vous avez séparé ce que vous voulez faire quand un bouton est cliqué avec comment déterminer si un bouton a été cliqué.

Déclarez simplement un événement, relancez-le si nécessaire et manipulez-le. Il ressemblera à ceci:

 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 

Mise à jour 2 – Grille étendue

Ce qui serait génial, c’est que si nous travaillions avec une grid qui faisait juste ces choses pour nous. Nous pourrions facilement répondre à la question initiale: you've added a button to your DataGridView and you want to run some code when it's clicked . Voici une approche qui étend le DataGridView . Cela ne vaut peut-être pas la peine de devoir fournir un contrôle personnalisé à chaque bibliothèque, mais au moins, il réutilise au maximum le code utilisé pour déterminer si un bouton a été cliqué.

Ajoutez simplement ceci à votre assemblée:

 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 

C’est tout. Ne le touchez plus jamais. Assurez-vous que votre DataGrid est de type DataGridViewExt lequel doit fonctionner exactement comme DataGridView. Sauf qu’il va également générer un événement supplémentaire que vous pouvez gérer comme ceci:

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

Cela est entièrement répondu ici pour WinForms: DataGridViewButtonColumn Class

et ici: Comment: répondre aux événements de bouton dans un contrôle GridView

pour Asp.Net en fonction du contrôle que vous utilisez réellement. (Votre question dit DataGrid, mais vous développez une application Windows, donc le contrôle que vous utiliserez est un DataGridView …)

Voici la meilleure réponse:

Vous ne pouvez pas implémenter un événement cliqué sur un bouton pour les cellules de bouton dans un DataGridViewButtonColumn. Au lieu de cela, vous utilisez l’événement CellClicked de DataGridView et déterminez si l’événement a été déclenché pour une cellule dans votre DataGridViewButtonColumn. Utilisez la propriété DataGridViewCellEventArgs.RowIndex de l’événement pour savoir sur quelle ligne a été cliqué.

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

trouvé ici: événement de clic de bouton dans datagridview

Cela résout mon problème.

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

Un peu tard pour la table ici, mais dans c # (vs2013) vous n’avez pas besoin d’utiliser des noms de colonnes non plus, en fait beaucoup de travail supplémentaire proposé par certaines personnes est complètement inutile.

La colonne est en fait créée en tant que membre du conteneur (le formulaire ou le contrôle utilisateur dans lequel vous avez placé DataGridView). À partir du code du concepteur (ce que vous n’êtes pas censé modifier sauf lorsque le concepteur casse quelque chose), vous voyez quelque chose comme:

 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; 

Donc, dans le gestionnaire CellContentClick, en plus de s’assurer que l’index de ligne n’est pas 0, il vous suffit de vérifier si la colonne cliquée est bien celle que vous voulez en comparant les références d’object:

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

Notez que la beauté de ceci est que tout changement de nom sera capturé par le compilateur. Si vous indexez avec un nom de texte qui change ou que vous mettez une majuscule incorrecte, vous êtes lié aux problèmes d’exécution. Ici, vous utilisez le nom d’un object que le concepteur crée en fonction du nom que vous avez fourni. Mais toute incompatibilité sera scope à votre attention par le compilateur.

Voici mon extrait de code pour déclencher l’événement click et transmettre la valeur à un autre formulaire:

 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 ssortingng x=myDataGridView.Rows[e.RowIndex].Cells[3].Value.ToSsortingng(); Form1 myform = new Form1(); myform.rowid= (int)x; myform.Show(); } } 

bien, je vais mordre.

vous aurez besoin de faire quelque chose comme ça – évidemment c’est tout métacode.

 button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method) 

qui “raccorde” la méthode IClicked_My_Button_method à l’événement Click du bouton. Maintenant, chaque fois que l’événement est “déclenché” depuis la classe propriétaire, notre méthode sera également déclenchée.

Dans la méthode IClicked_MyButton_met, il vous suffit de cliquer sur ce que vous voulez.

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

Les détails réels sont à vous, mais s’il y a quelque chose qui vous manque conceptuellement, faites-le moi savoir et je vais essayer de vous aider.

La plupart des solutions votées sont incorrectes, car ne peuvent pas fonctionner avec peu de boutons dans une ligne.

La meilleure solution sera le code suivant:

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

Il suffit d’append la méthode ToList() à la fin de votre liste, où se lier à datagridview DataSource:

 dataGridView1.DataSource = MyList.ToList(); 

Vous pouvez essayer celui-ci, vous ne vous soucierez pas beaucoup de l’ordre des colonnes.

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

Par exemple pour l’événement ClickCell dans 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); } 

Cordialement 🙂

En supposant par exemple que DataGridView ait des colonnes comme indiqué ci-dessous et que ses éléments liés aux données soient de type PrimalPallet vous pouvez utiliser la solution donnée ci-dessous.

entrer la description de l'image ici

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

Il est plus sûr d’accéder directement aux colonnes plutôt que d’utiliser dataGridView1.Columns["MyColumnName"] et il n’est pas nécessaire d’parsingr l’ sender sur DataGridView car il n’est pas nécessaire.

Si quelqu’un utilise C # (ou voir Note sur VB.NET ci-dessous) et a atteint ce point, mais est toujours bloqué, veuillez continuer.

La réponse de Joshua m’a aidé, mais pas complètement. Vous remarquerez que Peter a demandé “D’où auriez-vous le bouton?”, Mais sans réponse.

La seule façon dont cela a fonctionné pour moi était de faire l’une des choses suivantes pour append mon dossier d’événements (après avoir défini DataSource de mon DataGridView sur mon DataTable et après avoir ajouté DataGridViewButtonColumn à DataGridView):

Non plus:

 dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick); 

ou:

 dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick); 

Et puis ajoutez la méthode de gestionnaire (dataGridView1_CellClick ou dataGridView1_CellContentClick) indiquée dans les différentes réponses ci-dessus.

Remarque: VB.NET est différent de C # à cet égard, car nous pouvons simplement append une clause Handles à la signature de notre méthode ou émettre une instruction AddHandler comme décrit dans le document Microsoft ” Comment: appeler un gestionnaire d’événements dans Visual Basic ”