DataGridView 的右键菜单(ContextMenuStrip)

一、使用属性

DataGridView, DataGridViewColumn, DataGridViewRow, DataGridViewCell 有 ContextMenuStrip 属性。可以通过设定 ContextMenuStrip 对象来控制 DataGridView 的右键菜单的显示。 DataGridViewColumn 的 ContextMenuStrip 属性设定了 除了列头以外的单元格的右键菜单。 DataGridViewRow 的 ContextMenuStrip 属性设定了除了行头以外的单元格的右键菜单。DataGridViewCell 的  ContextMenuStrip 属性设定了指定单元格的右键菜单。

 

[C#]

1
2
3
4
5
6
7
8
9
10
// DataGridView 的 ContextMenuStrip 设定
DataGridView1.ContextMenuStrip = this .ContextMenuStrip1;
// 列的 ContextMenuStrip 设定
DataGridView1.Columns[0].ContextMenuStrip = this .ContextMenuStrip2;
// 列头的 ContextMenuStrip 设定
DataGridView1.Columns[0].HeaderCell.ContextMenuStrip = this .ContextMenuStrip2;
// 行的 ContextMenuStrip 设定
DataGridView1.Rows[0].ContextMenuStrip = this .ContextMenuStrip3;
// 单元格的 ContextMenuStrip 设定
DataGridView1[0, 0].ContextMenuStrip = this .ContextMenuStrip4;

 

对于单元格上的右键菜单的设定,优先顺序是: Cell > Row > Column > DataGridView

 

二、使用dataGridView的 CellContextMenuStripNeeded、RowContextMenuStripNeeded 事件

利用 CellContextMenuStripNeeded 事件可以设定单元格的右键菜单,尤其但需要右键菜单根据单元格值的变化而变化的时候(例如你需要判断cell的值大于10时使用ContextMenuStrip1,小于10时使用ContextMenuStrip2 ,那就需要用CellContextMenuStripNeeded事件来设置了)。比起使用循环遍历,使用该事件来设定右键菜单的效率更高。但是,在DataGridView使用了DataSource绑定而且是VirtualMode的时候,该事件将不被引发。

[C#]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// CellContextMenuStripNeeded事件处理方法
private  void  DataGridView1_CellContextMenuStripNeeded( object  sender,
     DataGridViewCellContextMenuStripNeededEventArgs e)
{
     DataGridView dgv = (DataGridView)sender;
if  (e.RowIndex < 0)
     {
// 列头的ContextMenuStrip设定
         e.ContextMenuStrip = this .ContextMenuStrip1;
     }
else  if  (e.ColumnIndex < 0)
     {
// 行头的ContextMenuStrip设定
         e.ContextMenuStrip = this .ContextMenuStrip2;
     }
else  if  (dgv[e.ColumnIndex, e.RowIndex].Value is  int )
     {
// 如果单元格值是整数时
         e.ContextMenuStrip = this .ContextMenuStrip3;
     }
}

 

同样,可以通过 RowContextMenuStripNeeded 事件来设定行的右键菜单。

[C#]

1
2
3
4
5
6
7
8
9
10
11
12
13
// RowContextMenuStripNeeded事件处理方法
private  void  DataGridView1_RowContextMenuStripNeeded( object  sender,
     DataGridViewRowContextMenuStripNeededEventArgs e)
{
     DataGridView dgv = (DataGridView)sender;
// 当"Column1"列是Bool型且为True时、设定其的ContextMenuStrip
object  boolVal = dgv[ "Column1" , e.RowIndex].Value;
     Console.WriteLine(boolVal);
if  (boolVal is  bool  && ( bool )boolVal)
     {
         e.ContextMenuStrip = this .ContextMenuStrip1;
     }
}

CellContextMenuStripNeeded 事件处理方法的参数中「e.ColumnIndex=-1」表示行头、「e.RowIndex=-1」表示列头。RowContextMenuStripNeeded则不存在「e.RowIndex=-1」的情况。

 

 

————————————————————分割线——————————————————————————————

1、上面只是设置ContextMenuStrip的方法,右键并不会改变当前的行号,也就是说:当前行号是1,但右键单击第2行,弹出ContextMenuStrip菜单,这时当前行依然是第1行,currentRow取得的数据也是第1行的数据,那么我们怎么使右键的同时改变当前行号呢?

可以使用CellMouseDown事件解决这一问题:

private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) 
        { 
            if (e.Button == MouseButtons.Right) 
            { 
               if (e.RowIndex >= 0) 
               { 
                dataGridView1.ClearSelection(); 
                dataGridView1.Rows[e.RowIndex].Selected = true; 
                dataGridView1.CurrentCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex]; 
                //contextMenuStrip_ListViewItemRightClick.Show(MousePosition.X, MousePosition.Y); 
               } 
            } 
        }

 

2、如果我们不需要根据单元格的值来区别设置不同的ContextMenuStrip,那么使用RowTemplate的ContextMenuStrip属性设置ContextMenuStrip就足够了。

 

——————————————————再分割——————————————————————————————

对于treeview也有类似的问题,解决方法:

 

//对于treeview可以应用mousedown事务

办法一:

1
2
3
4
5
6
7
8
9
10
11
private  void  treeView1_MouseDown( object  sender, MouseEventArgs e)
{
if  (e.Button == MouseButtons.Right)
{
TreeNode node = this .treeView1.GetNodeAt(e.Location);
if  (node != null
{
this .treeView1.SelectedNode = node;
}
}
}

办法二:

1
2
3
4
5
6
7
8
9
10
void  jcsTreeView1_MouseDown( object  sender, MouseEventArgs e)
         {
            System.Windows.Forms.TreeViewHitTestInfo hittestinfo = this .jcsTreeView1.HitTest(e.X ,e.Y);
if  (hittestinfo.Node != null
            {
                TreeViewHitTestLocations loc = hittestinfo.Location;
if (loc == TreeViewHitTestLocations.Label )
                  MessageBox.Show(hittestinfo.Node.Text);
            }
         }

你可能感兴趣的:(asp.net,WinForm,datagridview)