DGV上的鼠標事件,MouseDown 、MouseUp、CellMouseClick等事件可參考。
if (MouseButtons == MouseButtons.Right)
MessageBox.Show("OK");
// 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
? CellContextMenuStripNeeded、RowContextMenuStripNeeded 事件
利用 CellContextMenuStripNeeded 事件可以設定單元格的右鍵菜單,尤其但需要右鍵菜單根據單元格值的變化而變化的時候。比起使用循環遍歷,使用該事件來設定右鍵菜單的效率更高。但是,在DataGridView使用了DataSource綁定而且是VirtualMode的時候,該事件將不被引發。
// 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 事件來設定行的右鍵菜單。
// 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」的情況。
//引用地址 http://qianshao.blog.51cto.com/935360/201791
//How do you select a datagridview row on a right-click?
// Clear all the previously selected rows
foreach (DataGridViewRow row in yourDataGridView.Rows)
{
row.Selected = false;
}
// Get the selected Row
DataGridView.HitTestInfo info = yourDataGridView.HitTest( e.X, e.Y );
// Set as selected
yourDataGridView.Rows[info.RowIndex].Selected = true;
//You can use JvR's code in the MouseDown event of your DataGridView.
private void SubClassedGridView_MouseDown(object sender, MouseEventArgs e)
{
// Sets is so the right-mousedown will select a cell
DataGridView.HitTestInfo hti = this.HitTest(e.X, e.Y);
// Clear all the previously selected rows
this.ClearSelection();
// Set as selected
this.Rows[hti.RowIndex].Selected = true;
}
private void dataGridView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
dataGridView.CurrentCell = dataGridView[e.ColumnIndex, e.RowIndex];
}
}
控制右鍵菜單出現的位置為鼠標點擊的地方呢?
private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
{
int r = this.dataGridView1.HitTest(e.X, e.Y).RowIndex;
int c = this.dataGridView1.HitTest(e.X, e.Y).ColumnIndex;
if (r >= 0 && c >= 0) //點中Cell
{
DataGridViewCell hitcell = this.dataGridView1.Rows[r].Cells[c];
Point pscreen = this.dataGridView1.PointToScreen(e.Location);
Point pForm = this.PointToClient(pscreen);
this.textBox1.Text = pscreen.ToString(); //相對屏幕的坐標
this.textBox2.Text = pForm.ToString(); //相對當前Form的坐標
}
else //沒點中Cell
{
}
}
CellContextMenuStripNeeded 事件僅在設置了 DataGridView 控件的 DataSource 屬性或者該控件的 VirtualMode 屬性為 true 時發生。
處理 CellContextMenuStripNeeded 事件時,每當用戶右擊單元格時,就會顯示您在處理程序中指定的快捷菜單。當需要顯示由某個單元格的當前狀態或當前值決定的快捷菜單時,此事件就很有用。
只要檢索 DataGridViewCell.ContextMenuStrip 屬性的值,無論是通過編程方式還是用戶右擊某個單元格,CellContextMenuStripNeeded 事件都會發生。
可以使用 ColumnIndex 和 RowIndex 屬性來確定單元格的狀態或值,並使用這些信息來設置 ContextMenuStrip 屬性。此屬性是使用單元格的 ContextMenuStrip 屬性值初始化的,該值會被事件值重寫。
在處理大量數據時應處理 CellContextMenuStripNeeded 事件,這樣,在為多個單元格設置單元格 ContextMenuStrip 值時,可以避免性能受到影響。有關更多信息,請參見 縮放 Windows 窗體 DataGridView 控件的最佳做法。
還可以通過設置行的 ContextMenuStrip 屬性或處理 DataGridView 控件的 RowContextMenuStripNeeded 事件來為各個行(而非各個單元格)指定快捷菜單。單元格的 ContextMenuStrip 屬性設置重寫行的 ContextMenuStrip 屬性設置,CellContextMenuStripNeeded 事件既重寫 RowContextMenuStripNeeded 事件,又重寫行的 ContextMenuStrip 屬性設置。不過,您可以為單元格快捷菜單指定 空引用(在 Visual Basic 中為 Nothing) 來阻止重寫行快捷菜單。
有關處理事件的更多信息,請參見 使用事件。
當創建 DataGridViewCellContextMenuStripNeededEventHandler 委托時,將標識處理事件的方法。若要使該事件與事件處理程序相關聯,請將該委托的一個實例添加到事件中。除非移除了該委托,否則每當發生該事件時就調用事件處理程序。有關事件處理程序委托的更多信息,請參見 事件和委托。
示例
private ToolStripMenuItem wholeTable = new ToolStripMenuItem(); private ToolStripMenuItem lookUp = new ToolStripMenuItem(); private ContextMenuStrip strip; private string cellErrorText; private void dataGridView1_CellContextMenuStripNeeded(object sender, DataGridViewCellContextMenuStripNeededEventArgs e) { cellErrorText = String.Empty; if (strip == null) { strip = new ContextMenuStrip(); lookUp.Text = "Look Up"; wholeTable.Text = "See Whole Table"; strip.Items.Add(lookUp); strip.Items.Add(wholeTable); } e.ContextMenuStrip = strip; } private void wholeTable_Click(object sender, EventArgs e) { dataGridView1.DataSource = Populate("Select * from employees", true); } private DataGridViewCellEventArgs theCellImHoveringOver; private void dataGridView1_CellMouseEnter(object sender, DataGridViewCellEventArgs e) { theCellImHoveringOver = e; } private DataGridViewCellEventArgs cellErrorLocation; private void lookUp_Click(object sender, EventArgs e) { try { dataGridView1.DataSource = Populate("Select * from employees where " + dataGridView1.Columns[theCellImHoveringOver.ColumnIndex].Name + " = '" + dataGridView1.Rows[theCellImHoveringOver.RowIndex]. Cells[theCellImHoveringOver.ColumnIndex].Value + "'", true); } catch (SqlException) { cellErrorText = "Can't look this cell up"; cellErrorLocation = theCellImHoveringOver; } } private void dataGridView1_CellErrorTextNeeded(object sender, DataGridViewCellErrorTextNeededEventArgs e) { if (cellErrorLocation != null) { if (e.ColumnIndex == cellErrorLocation.ColumnIndex && e.RowIndex == cellErrorLocation.RowIndex) { e.ErrorText = cellErrorText; } } } private DataTable Populate(string query, bool resetUnsharedCounter) { if (resetUnsharedCounter) { ResetCounter(); } // Alter the data source as necessary SqlDataAdapter adapter = new SqlDataAdapter(query, new SqlConnection("Integrated Security=SSPI;Persist Security Info=False;" + "Initial Catalog=Northwind;Data Source=localhost")); DataTable table = new DataTable(); table.Locale = System.Globalization.CultureInfo.InvariantCulture; adapter.Fill(table); return table; } private Label count = new Label(); private int unsharedRowCounter; private void ResetCounter() { unsharedRowCounter = 0; count.Text = unsharedRowCounter.ToString(); }