【问题标题】:Right click to select a row in a Datagridview and show a menu to delete it右键单击以选择 Datagridview 中的一行并显示一个菜单以将其删除
【发布时间】:2011-03-03 09:14:02
【问题描述】:

我的 DataGridView 中的列很少,并且行中有数据。我在这里看到了一些解决方案,但我无法将它们组合起来!

Simply a way to right-click on a row, it will select the whole row and show a menu with an option to delete the row and when the option selected it will delete the row.

我做了几次尝试,但都没有成功,而且看起来很乱。我该怎么办?

【问题讨论】:

  • 你的问题太模糊了。在您遇到问题的地方添加更多详细信息。您正在尝试做的事情并不是很困难。

标签: c# select datagridview contextmenu right-click


【解决方案1】:

我终于解决了:

  • 在 Visual Studio 中,使用名为“DeleteRow”的项目创建 ContextMenuStrip

  • 然后在 DataGridView 链接 ContextMenuStrip

使用下面的代码帮助我让它工作。

this.MyDataGridView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MyDataGridView_MouseDown);
this.DeleteRow.Click += new System.EventHandler(this.DeleteRow_Click);

这是最酷的部分

private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
{
    if(e.Button == MouseButtons.Right)
    {
        var hti = MyDataGridView.HitTest(e.X, e.Y);
        MyDataGridView.ClearSelection();
        MyDataGridView.Rows[hti.RowIndex].Selected = true;
    }
}

private void DeleteRow_Click(object sender, EventArgs e)
{
    Int32 rowToDelete = MyDataGridView.Rows.GetFirstRow(DataGridViewElementStates.Selected);
    MyDataGridView.Rows.RemoveAt(rowToDelete);
    MyDataGridView.ClearSelection();
}

【讨论】:

  • 嗨,您在 DeleteRow_Click 中使用什么控件?
  • 当网格上出现ContextMenuStripNeeded 事件时,此答案似乎不起作用。使用CellMouseDown 有效。
  • 非常有帮助,谢谢!如果您使用AllowUserToAddRows,您可能需要在执行RemoveAt() 之前检查MyDataGridView.Rows[rowToDelete].IsNewRow,以防用户右键单击新行。
  • 感谢分享!我建议也检查命中类型: if (hit.Type == DataGridViewHitTestType.Cell) { ... } 请参阅:msdn.microsoft.com/en-us/library/…
【解决方案2】:

为了这个问题的完整性,最好使用 Grid 事件而不是鼠标。

首先设置你的数据网格属性:

SelectionMode 到 FullRowSelect 和 RowTemplate / ContextMenuStrip 到上下文菜单。

创建 CellMouseDown 事件:-

private void myDatagridView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        int rowSelected = e.RowIndex;
        if (e.RowIndex != -1)
        {
            this.myDatagridView.ClearSelection();
            this.myDatagridView.Rows[rowSelected].Selected = true;
        }
        // you now have the selected row with the context menu showing for the user to delete etc.
    }
}

【讨论】:

  • 当存在ContextMenuStripNeeded 时,此答案有效。基于MouseDown 的解决方案没有。
  • @peter 如果选择了多行,如何获取行的索引?
  • 您好 vbp,如果您还没有回答,我认为您需要提出一个新问题,这个问题是指仅选择 1 行。
【解决方案3】:
private void dgvOferty_CellContextMenuStripNeeded(object sender, DataGridViewCellContextMenuStripNeededEventArgs e)
    {
        dgvOferty.ClearSelection();
        int rowSelected = e.RowIndex;
        if (e.RowIndex != -1)
        {
            this.dgvOferty.Rows[rowSelected].Selected = true;
        }
        e.ContextMenuStrip = cmstrip;
    }

多田:D。最简单的方式时期。对于自定义单元格,只需稍作修改即可。

【讨论】:

  • 最佳方法,仅在使用键盘时也有效。但是请注意:仅在附加了 DataSource 时才有效。 MSDN 关于 DataGridView.CellContextMenuStripNeeded 事件:“只有当设置了 DataGridView 控件的 DataSource 属性或其 VirtualMode 属性为 true 时,才会发生 CellContextMenuStripNeeded 事件。”
  • cmstrip 变量引用是什么?
  • @reformed 它引用了从工具箱中添加的 ContextMenuStrip。
【解决方案4】:

只为 mousedown 添加事件要容易得多:

private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        var hti = MyDataGridView.HitTest(e.X, e.Y);
        MyDataGridView.Rows[hti.RowIndex].Selected = true;
        MyDataGridView.Rows.RemoveAt(rowToDelete);
        MyDataGridView.ClearSelection();
    }
}

这更容易。当然,您必须像已经提到的那样初始化 mousedown 事件:

this.MyDataGridView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MyDataGridView_MouseDown);

在你的构造函数中。

【讨论】:

    【解决方案5】:

    对此问题的所有答案均基于鼠标单击事件。您还可以将ContenxtMenuStrip 分配给您的DataGridview 并检查DataGridView 上的用户RightMouseButtons 时是否选择了一行并决定是否要查看ContenxtMenuStrip .您可以通过在ContextMenuStripOpening event 中设置CancelEventArgs.Cancel 值来做到这一点

        private void MyContextMenuStrip_Opening(object sender, CancelEventArgs e)
        {
            //Only show ContextMenuStrip when there is 1 row selected.
            if (MyDataGridView.SelectedRows.Count != 1) e.Cancel = true;
        }
    

    但是,如果您有多个上下文菜单条,每个菜单条都包含不同的选项,具体取决于选择,我自己也会使用鼠标单击方法。

    【讨论】:

      【解决方案6】:

      基于@Data-Base 的回答,直到选择模式 FullRow 才会起作用

        MyDataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
      

      但如果你需要让它在 CellSelect 模式下工作

       MyDataGridView.SelectionMode = DataGridViewSelectionMode.CellSelect;
      
       // for cell selection
       private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
       {
        if(e.Button == MouseButtons.Right)
          {
             var hit = MyDataGridView.HitTest(e.X, e.Y);
             MyDataGridView.ClearSelection();
      
             // cell selection
             MyDataGridView[hit.ColumnIndex,hit.RowIndex].Selected = true;
         }
      }
      
      private void DeleteRow_Click(object sender, EventArgs e)
      {
         int rowToDelete = MyDataGridView.Rows.GetFirstRow(DataGridViewElementStates.Selected);
         MyDataGridView.Rows.RemoveAt(rowToDelete);
         MyDataGridView.ClearSelection();
      }
      

      【讨论】:

        【解决方案7】:
        private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
        {
            if(e.Button == MouseButtons.Right)
            {
                MyDataGridView.ClearSelection();
                MyDataGridView.Rows[e.RowIndex].Selected = true;
            }
        }
        
        private void DeleteRow_Click(object sender, EventArgs e)
        {
            Int32 rowToDelete = MyrDataGridView.Rows.GetFirstRow(DataGridViewElementStates.Selected);
            MyDataGridView.Rows.RemoveAt(rowToDelete);
            MyDataGridView.ClearSelection();
        }
        

        【讨论】:

          【解决方案8】:
          private void dataGridView1_CellContextMenuStripNeeded(object sender, 
          DataGridViewCellContextMenuStripNeededEventArgs e)
          {            
              if (e.RowIndex != -1)
              {
                  dataGridView1.ClearSelection();
                  this.dataGridView1.Rows[e.RowIndex].Selected = true;
                  e.ContextMenuStrip = contextMenuStrip1;
              }
          }
          

          【讨论】:

            【解决方案9】:

            这对我来说没有任何错误:

            this.dataGridView2.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MyDataGridView_MouseDown); 
            this.dataGridView2.Click += new System.EventHandler(this.DeleteRow_Click);
            

            还有这个

            private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Right)
                {
                    var hti = dataGridView2.HitTest(e.X, e.Y);
                    dataGridView2.ClearSelection();
                    dataGridView2.Rows[hti.RowIndex].Selected = true;
                }
            
            }
            
            
            private void DeleteRow_Click(object sender, EventArgs e)
            {
                Int32 rowToDelete = dataGridView2.Rows.GetFirstRow(DataGridViewElementStates.Selected);
                if (rowToDelete == -1) { }
                else 
                {
                    dataGridView2.Rows.RemoveAt(rowToDelete);
                    dataGridView2.ClearSelection();
                }
            }
            

            【讨论】:

              【解决方案10】:

              您还可以通过在事件代码中使用以下内容来简化此操作:

              private void MyDataGridView_MouseDown(object sender, MouseEventArgs e) 
              {     
                  if (e.Button == MouseButtons.Right)     
                  {         
                      rowToDelete = e.RowIndex;
                      MyDataGridView.Rows.RemoveAt(rowToDelete);         
                      MyDataGridView.ClearSelection();     
                  } 
              }
              

              【讨论】:

              • 这只会删除没有警告或确认的行。我确定 OP 不希望这样。
              【解决方案11】:

              看这里可以使用DataGridViewRowTemplate属性来完成。

              注意:此代码未经测试,但我以前使用过此方法。

              // Create DataGridView
              DataGridView gridView = new DataGridView();
              gridView.AutoGenerateColumns = false;
              gridView.Columns.Add("Col", "Col");
              
              // Create ContextMenu and set event
              ContextMenuStrip cMenu = new ContextMenuStrip();
              ToolStripItem mItem = cMenu.Items.Add("Delete");
              mItem.Click += (o, e) => { /* Do Something */ };           
              
              // This makes all rows added to the datagridview use the same context menu
              DataGridViewRow defaultRow = new DataGridViewRow();
              defaultRow.ContextMenuStrip = cMenu;
              

              就这么简单!

              【讨论】:

                【解决方案12】:

                我有一个新的解决方法可以得到相同的结果,但是代码更少。 对于 Winforms ......这是葡萄牙语的例子 一步步跟进

                1. 在表单中创建一个 contextMenuStrip 并创建一项
                2. 为此 contextMenuStrip 签署一个事件单击 (OnCancelarItem_Click)
                3. 在 gridview 上创建事件“UserDeletingRow” 现在...您正在模拟用户的按键 del

                  你不会忘记在 gridview 上启用删除,对吧?!

                最后...

                【讨论】:

                  猜你喜欢
                  • 2012-03-05
                  • 2013-05-21
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-08-19
                  • 1970-01-01
                  • 2011-06-18
                  • 2011-09-13
                  相关资源
                  最近更新 更多