如何处理Datagridviewbutton列中的单击事件?

我正在开发一个使用C#的Windows应用程序。 我正在使用DataGridView来显示数据。 我已经添加了一个button列。 我想知道如何处理DataGridView中该button上的单击事件。

你已经添加了一个button到你的DataGridView ,你想运行一些代码,当它被点击。
容易peasy – 只要按照下列步骤:

注意事项:

首先,这是不该做的:

我会避免在这里的其他答案的build议,甚至由MSDN的文档提供硬编码列索引或列名称,以确定是否一个button被点击。 点击事件注册整个网格,所以不知何故,你需要确定一个button被点击,但你不应该这样做,假设你的button住在一个特定的列名或索引…有一个更简单的方法…

另外,要小心你想要处理的事件。 再次,文档和许多例子得到这个错误。 大多数示例处理将触发的CellClick事件:

当单元格的任何部分被点击时。

…但是也会在点击标题时触发。 这就需要添加额外的代码来确定e.RowIndex值是否小于0

而是处理仅发生的CellContentClick

当单元格内的内容被点击时

无论出于何种原因, 标题也被视为单元格中的“内容”,因此我们仍然需要检查下面的内容。

DOS:

所以这里是你应该做的:

首先, 发件人强制typesDataGridView在devise时暴露它的内部属性。 您可以修改参数的types,但有时候会使添加或删除处理程序变得棘手。

接下来,要查看是否单击了button,只需检查确保引发该事件的列的types为DataGridViewButtonColumn 。 因为我们已经将发件人转换为DataGridViewtypes,所以我们可以获取Columns集合,并使用e.ColumnIndexselect当前列。 然后检查该对象的types是DataGridViewButtonColumn

当然,如果你需要根据每个网格区分多个button,那么你可以根据列名或索引来select,但这不应该是你的第一次检查。 一定要确保首先点击一个button,然后适当地处理其他事情。 在大多数情况下,每个网格只有一个button,您可以直接跳到比赛。

把它放在一起:

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 

更新1 – 自定义事件

如果你想有一点乐趣,你可以添加自己的事件,每当在DataGrid上单击一个button时引发。 你不能把它添加到DataGrid本身,而不会让inheritance等麻烦,但你可以添加一个自定义的事件到你的窗体,并在适当时触发它。 这是一个更多的代码,但好处是你已经分离出你想要做什么,当点击一个button,如何确定是否点击一个button。

只要声明一个事件,在适当的时候提出来处理。 它看起来像这样:

 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的方法。 可能不值得为每个库提供自定义控件的麻烦,但至less它最大限度地重用用于确定button被单击的代码。

只需将其添加到您的程序集:

 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 

而已。 切勿再次触摸它。 确保你的DataGridtypes是DataGridViewExt ,它应该和DataGridViewExt完全一样。 除了它也会引发一个额外的事件,你可以这样处理:

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

这里完全回答了WinForms: DataGridViewButtonColumn类

在这里: 如何:在GridView控件中响应button事件

为Asp.Net取决于你实际使用的控制。 (你的问题是说DataGrid,但是你正在开发一个Windows应用程序,所以你使用的控件是一个DataGridView …)

这是更好的答案:

DataGridViewButtonColumn中的button单元不能实现button单击事件。 而是使用DataGridView的CellClicked事件,并确定是否为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); } } 

在这里find: datagridview中的button点击事件

这解决了我的问题。

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

这里是我的代码片段来触发点击事件,并将值传递给另一种forms:

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

这里有点迟到了,但在c#(vs2013)中也不需要使用列名,实际上很多人提出的额外工作是完全没有必要的。

该列实际上是作为容器的成员(您将DataGridView放入的表单或用户控件)创build的。 从devise器代码(除非devise者打破了某些东西,否则你不应该编辑这些东西),你会看到如下的东西:

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

请注意,这样做的好处是任何名称变化都会被编译器捕获。 如果您使用文本名称进行索引更改,或者使用不正确的大写,则会出现运行时问题。 在这里你实际上使用了一个对象的名字,devise师根据你提供的名字创build一个对象。 但编译器会引起您的任何不匹配。

好吧,我会咬人。

你需要做这样的事情 – 显然是所有的元代码。

 button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method) 

将“IClicked_My_Button_method”方法“钩住”到button的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. } 

这里的实际细节取决于你,但是如果你还有其他的东西没有在概念上让我知道,我会尽力帮助。

大多数投票解决scheme是错误的,因为不能在一行中使用几个button。

最好的解决scheme将是以下代码:

 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 DataSource:

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

例如对于Windows窗体中的ClickCell事件。

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

问候 :)