Mặc dù câu hỏi này đã cũ, nhưng câu trả lời không phù hợp. Các menu ngữ cảnh có các sự kiện riêng trên DataGridView. Có một sự kiện cho menu ngữ cảnh hàng và menu ngữ cảnh ô.
Lý do mà những câu trả lời này không phù hợp là chúng không giải thích cho các chương trình hoạt động khác nhau. Các tùy chọn trợ năng, kết nối từ xa hoặc cổng Metro / Mono / Web / WPF có thể không hoạt động và các phím tắt sẽ không hoạt động (Shift + F10 hoặc phím Trình đơn ngữ cảnh).
Việc chọn ô khi nhấp chuột phải phải được xử lý thủ công. Việc hiển thị menu ngữ cảnh không cần được xử lý vì việc này do giao diện người dùng xử lý.
Điều này hoàn toàn bắt chước cách tiếp cận được sử dụng bởi Microsoft Excel. Nếu một ô là một phần của dải ô đã chọn, thì lựa chọn ô không thay đổi và cũng không thay đổi CurrentCell
. Nếu không, phạm vi cũ sẽ bị xóa và ô được chọn và trở thành CurrentCell
.
Nếu bạn không rõ về điều này, CurrentCell
thì bàn phím có tiêu điểm khi bạn nhấn các phím mũi tên. Selected
là liệu nó có phải là một phần của SelectedCells
. Menu ngữ cảnh sẽ hiển thị khi nhấp chuột phải do giao diện người dùng xử lý.
private void dgvAccount_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex != -1 && e.RowIndex != -1 && e.Button == System.Windows.Forms.MouseButtons.Right)
{
DataGridViewCell c = (sender as DataGridView)[e.ColumnIndex, e.RowIndex];
if (!c.Selected)
{
c.DataGridView.ClearSelection();
c.DataGridView.CurrentCell = c;
c.Selected = true;
}
}
}
Các phím tắt không hiển thị menu ngữ cảnh theo mặc định, vì vậy chúng tôi phải thêm chúng vào.
private void dgvAccount_KeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyCode == Keys.F10 && e.Shift) || e.KeyCode == Keys.Apps)
{
e.SuppressKeyPress = true;
DataGridViewCell currentCell = (sender as DataGridView).CurrentCell;
if (currentCell != null)
{
ContextMenuStrip cms = currentCell.ContextMenuStrip;
if (cms != null)
{
Rectangle r = currentCell.DataGridView.GetCellDisplayRectangle(currentCell.ColumnIndex, currentCell.RowIndex, false);
Point p = new Point(r.X + r.Width, r.Y + r.Height);
cms.Show(currentCell.DataGridView, p);
}
}
}
}
Tôi đã làm lại mã này để hoạt động tĩnh, vì vậy bạn có thể sao chép và dán chúng vào bất kỳ sự kiện nào.
Điều quan trọng là sử dụng CellContextMenuStripNeeded
vì nó sẽ cung cấp cho bạn menu ngữ cảnh.
Đây là một ví dụ sử dụng CellContextMenuStripNeeded
nơi bạn có thể chỉ định menu ngữ cảnh nào sẽ hiển thị nếu bạn muốn có các menu khác nhau trên mỗi hàng.
Trong bối cảnh MultiSelect
này là True
và SelectionMode
đang FullRowSelect
. Đây chỉ là một ví dụ và không phải là một giới hạn.
private void dgvAccount_CellContextMenuStripNeeded(object sender, DataGridViewCellContextMenuStripNeededEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
if (e.RowIndex == -1 || e.ColumnIndex == -1)
return;
bool isPayment = true;
bool isCharge = true;
foreach (DataGridViewRow row in dgv.SelectedRows)
{
if ((string)row.Cells["P/C"].Value == "C")
isPayment = false;
else if ((string)row.Cells["P/C"].Value == "P")
isCharge = false;
}
if (isPayment)
e.ContextMenuStrip = cmsAccountPayment;
else if (isCharge)
e.ContextMenuStrip = cmsAccountCharge;
}
private void cmsAccountPayment_Opening(object sender, CancelEventArgs e)
{
int itemCount = dgvAccount.SelectedRows.Count;
string voidPaymentText = "&Void Payment"; // to be localized
if (itemCount > 1)
voidPaymentText = "&Void Payments"; // to be localized
if (tsmiVoidPayment.Text != voidPaymentText) // avoid possible flicker
tsmiVoidPayment.Text = voidPaymentText;
}
private void cmsAccountCharge_Opening(object sender, CancelEventArgs e)
{
int itemCount = dgvAccount.SelectedRows.Count;
string deleteChargeText = "&Delete Charge"; //to be localized
if (itemCount > 1)
deleteChargeText = "&Delete Charge"; //to be localized
if (tsmiDeleteCharge.Text != deleteChargeText) // avoid possible flicker
tsmiDeleteCharge.Text = deleteChargeText;
}
private void tsmiVoidPayment_Click(object sender, EventArgs e)
{
int paymentCount = dgvAccount.SelectedRows.Count;
if (paymentCount == 0)
return;
bool voidPayments = false;
string confirmText = "Are you sure you would like to void this payment?"; // to be localized
if (paymentCount > 1)
confirmText = "Are you sure you would like to void these payments?"; // to be localized
voidPayments = (MessageBox.Show(
confirmText,
"Confirm", // to be localized
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button2
) == DialogResult.Yes);
if (voidPayments)
{
// SQLTransaction Start
foreach (DataGridViewRow row in dgvAccount.SelectedRows)
{
//do Work
}
}
}
private void tsmiDeleteCharge_Click(object sender, EventArgs e)
{
int chargeCount = dgvAccount.SelectedRows.Count;
if (chargeCount == 0)
return;
bool deleteCharges = false;
string confirmText = "Are you sure you would like to delete this charge?"; // to be localized
if (chargeCount > 1)
confirmText = "Are you sure you would like to delete these charges?"; // to be localized
deleteCharges = (MessageBox.Show(
confirmText,
"Confirm", // to be localized
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button2
) == DialogResult.Yes);
if (deleteCharges)
{
// SQLTransaction Start
foreach (DataGridViewRow row in dgvAccount.SelectedRows)
{
//do Work
}
}
}