首页 文章

如何在Datagridview中的Button列中处理click事件?

提问于
浏览
112

我正在使用C#开发一个Windows应用程序 . 我正在使用 DataGridView 来显示数据 . 我在其中添加了一个按钮列 . 我想知道如何在DataGridView中处理该按钮上的click事件 .

14 回答

  • 0

    这是我的代码片段,用于触发click事件并将值传递给另一个表单:

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

    有点晚了这里的表,但在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();
            }
        }
    }
    

    请注意,这样做的好处是任何名称更改都将被编译器捕获 . 如果您使用更改的文本名称进行索引,或者您错误地将其大写,那么您将受到运行时问题的限制 . 在这里,您实际使用了对象的名称,设计者根据您提供的名称创建对象的名称 . 但编译器会引起您的注意 .

  • 9

    您已经为 DataGridView 添加了一个按钮,并且您希望在单击时运行一些代码 .
    容易腻 - 只需按照以下步骤操作:

    不应该做的事:

    首先,这是 NOT 要做的事情:

    我会在这里避免一些其他答案中的建议,甚至由documentation at MSDN提供硬编码列索引或列名以确定是否单击了一个按钮 . click事件为整个网格注册,因此您需要确定单击了一个按钮,但是您不应该通过假设您的按钮位于特定的列名称或索引中而这样做...这是一种更简单的方法...

    另外,请注意您要处理的事件 . 同样,文档和许多示例都错了 . 大多数示例处理将触发的CellClick事件:

    单击单元格的任何部分时 .

    ...但是每当单击行 Headers 时也会触发 . 这需要添加额外的代码,以确定 e.RowIndex 值是否小于0

    而是处理只发生的CellContentClick

    单击单元格中的内容时

    无论出于何种原因,列 Headers 在单元格中也被视为'content',因此我们仍然需要检查以下内容 .

    Dos:

    所以这就是你应该做的:

    首先,强制发送者键入 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
    

    更新1 - 自定义事件

    如果您想获得一些乐趣,只要在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
    

    更新2 - 扩展网格

    如果我们正在为我们做这些事情的网格工作,那将是多么伟大的事情 . 我们可以轻松回答最初的问题: 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
    
  • 0

    WinForms在这里得到了充分的回答:DataGridViewButtonColumn Class

    在这里:How to: Respond to Button Events in a GridView Control

    对于Asp.Net,取决于您实际使用的控件 . (你的问题是DataGrid,但是你正在开发一个Windows应用程序,所以你在那里使用的控件是一个DataGridView ...)

  • 207

    这是更好的答案:

    您无法在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);
      }
    }
    

    在这里找到:button click event in datagridview

  • 0

    这解决了我的问题 .

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

    假设例如 DataGridView 具有下面给出的列,并且其数据绑定项的类型为 PrimalPallet ,则可以使用下面给出的解决方案 .

    enter image description here

    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 ,因为它不需要 .

  • 0

    好的,我会咬人的 .

    你需要做这样的事情 - 显然它的所有元代码 .

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

    这里的实际细节取决于你,但如果还有其他任何你遗漏的概念,请告诉我,我会尽力帮助你 .

  • 0

    大多数投票解决方案都是错误的,因为无法在一行中使用少量按钮 .

    最佳解决方案将是以下代码:

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

    只需将 ToList() 方法添加到列表的末尾,其中绑定到datagridview DataSource:

    dataGridView1.DataSource = MyList.ToList();
    
  • 1

    你可以尝试这个,你不会太在意列的排序 .

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

    例如,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);
                    }
    

    问候 :)

  • 15

    如果有人使用C#(或者参见下面关于VB.NET的注释)并且已达到这一点,但仍然卡住,请继续阅读 .

    约书亚的回答帮助了我,但并非一直如此 . 你会注意到彼得问“你从哪里得到按钮?”,但没有得到答复 .

    它对我有用的唯一方法是执行以下操作之一来添加我的事件处理程序(在将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子句添加到我们的方法's signature or issue an AddHandler statement as described in the Microsoft doc' s“How to: Call an Event Handler in Visual Basic

  • 2

    您将在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);
    

相关问题