我正在使用C#开发Windows应用程序。我DataGridView
用来显示数据。我在其中添加了一个按钮列。我想知道如何处理DataGridView中该按钮上的click事件。
我正在使用C#开发Windows应用程序。我DataGridView
用来显示数据。我在其中添加了一个按钮列。我想知道如何处理DataGridView中该按钮上的click事件。
Answers:
您已经在按钮上添加了一个按钮,DataGridView
并且希望在单击该按钮时运行一些代码。
简单轻松-只需按照以下步骤操作:
首先,这是不可以做的事情:
我会避免这里的其他答案中的建议,甚至会避免MSDN文档提供的建议来对列索引或列名进行硬编码,以确定是否单击了按钮。click事件会在整个网格中注册,因此您需要以某种方式确定按钮是否已单击,但不应通过假设按钮位于特定的列名或索引中来进行此操作……这是一种更简单的方法……
另外,请注意要处理的事件。同样,文档和许多示例也弄错了这一点。大多数示例处理CellClick
将触发的事件:
单击单元格的任何部分时。
...但是每当单击行标题时也会触发。这就需要添加额外的代码来简单地确定该e.RowIndex
值是否小于0
而是处理CellContentClick
仅发生的:
单击单元格中的内容时
无论出于何种原因,列标题也被视为单元格中的“内容”,因此我们仍然必须在下面进行检查。
所以这是你应该做的:
首先,将发送方强制转换为类型DataGridView
以在设计时公开其内部属性。您可以修改参数的类型,但这有时会使添加或删除处理程序变得棘手。
接下来,要查看是否单击了按钮,只需检查以确保引发事件的列的类型DataGridViewButtonColumn
。因为我们已经将发送方强制转换为类型DataGridView
,所以我们可以获取Columns
集合并使用选择当前列e.ColumnIndex
。然后检查该对象是否为类型DataGridViewButtonColumn
。
当然,如果需要区分每个网格的多个按钮,则可以基于列名称或索引进行选择,但这不应该是您的第一眼检查。始终确保先单击一个按钮,然后再适当处理其他任何事情。在大多数情况下,每个网格只有一个按钮,您可以直接跳到比赛中。
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
如果您想找点乐子,则可以添加自己的事件,只要在DataGrid上单击一个按钮即可。您不能将其添加到DataGrid本身,而不会弄乱继承等,但是您可以在表单中添加自定义事件,并在适当时触发它。还有更多代码,但是好处是,您已经分离出单击按钮时要执行的操作以及如何确定是否单击了按钮。
只需声明一个事件,在适当的时候引发它,然后处理它即可。它看起来像这样:
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
最好的是,如果我们正在与一个为我们做这些事情的网格一起工作。我们可以轻松回答最初的问题:you've added a button to your DataGridView and you want to run some code when it's clicked
。这是扩展的方法DataGridView
。不必为每个库都提供自定义控件而麻烦,但是至少它最大程度地重用了用于确定是否单击按钮的代码。
只需将其添加到您的程序集中:
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
而已。永远不要再碰它。确保您的DataGrid的类型DataGridViewExt
应与DataGridView完全相同。除了会引发一个额外的事件,您可以像这样处理:
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); } } }
对于WinForms,这里已完全回答:DataGridViewButtonColumn类
取决于您实际使用的控件。(您的问题是说DataGrid,但是您正在开发Windows应用程序,因此要使用的控件中有一个DataGridView ...)
dataGridView1_CellClick
该代码。您能否更新您的答案并给我一些描述。
这是更好的答案:
您不能为DataGridViewButtonColumn中的按钮单元实现按钮单击事件。而是使用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);
}
}
在这里找到: datagridview中的按钮单击事件
这里的表格有点晚了,但是在c#(vs2013)中,您也不需要使用列名,实际上,有些人建议的许多额外工作是完全不必要的。
该列实际上是作为容器的成员(您将DataGridView放入的窗体或用户控件)创建的。从设计器代码(除了设计器破坏某些内容之外,您不应该编辑的内容)中,您将看到类似以下内容的内容:
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();
}
}
}
注意,这样做的好处是编译器会捕获任何名称更改。如果使用更改的文本名称进行索引或大小写不正确,则必然会遇到运行时问题。在这里,您实际上使用的是设计人员根据您提供的名称创建的对象的名称。但是,任何不匹配都会引起编译器的注意。
这是触发点击事件并将值传递给另一种形式的代码片段:
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();
}
}
例如,假设DataGridView
具有下面给出的列,并且其数据绑定项的类型为PrimalPallet
您可以使用下面给出的解决方案。
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.
}
}
}
直接访问列而不是使用列是更安全的,dataGridView1.Columns["MyColumnName"]
并且不需要解析sender
到,DataGridView
因为不需要。
很好,我会咬。
您将需要执行以下操作-显然是所有元代码。
button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method)
会“钩” IClicked_My_Button_method方法直到按钮的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.
}
实际的详细信息取决于您,但是如果您在概念上还有其他遗漏,请告诉我,我将尽力提供帮助。
投票最多的解决方案是错误的,因为不能连续使用几个按钮。
最佳解决方案是以下代码:
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");
}
}
您可以尝试这一步,您不会在乎列的顺序。
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);
}
问候 :)
如果有人正在使用C#(或参见下面的有关VB.NET的注释)并且已经达到了这一点,但仍然无法解决,请继续阅读。
约书亚(Joshua)的回答对我有所帮助,但并非一直如此。您会注意到Peter问“您将从何处获得按钮?”,但未得到回答。
它对我有用的唯一方法是执行以下操作之一以添加事件处理程序(将DataGridView的DataSource设置为DataTable并将DataGridViewButtonColumn添加到DataGridView之后):
要么:
dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);
要么:
dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);
然后添加上面各种答案中所示的处理程序方法(dataGridView1_CellClick或dataGridView1_CellContentClick)。
注意:VB.NET在这方面与C#不同,因为我们可以简单地将Handles子句添加到方法的签名中或发出AddHandler语句,如Microsoft文档的“ 如何:在Visual Basic中调用事件处理程序 ”中所述。
您将在dataGridView中添加这样的按钮列
DataGridViewButtonColumn mButtonColumn0 = new DataGridViewButtonColumn();
mButtonColumn0.Name = "ColumnA";
mButtonColumn0.Text = "ColumnA";
if (dataGridView.Columns["ColumnA"] == null)
{
dataGridView.Columns.Insert(2, mButtonColumn0);
}
然后,您可以在单元格单击事件中添加一些操作。我发现这是最简单的方法。
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.
}
}
我发现Cell Click事件经常自动订阅。因此,我不需要下面的代码。但是,如果未订阅您的单元格单击事件,则为dataGridView添加此行代码。
this.dataGridView.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellClick);