如何处理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
。 因为我们已经将发件人转换为DataGridView
types,所以我们可以获取Columns
集合,并使用e.ColumnIndex
select当前列。 然后检查该对象的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); }
问候 :)