이 질문은 오래되었지만 대답은 적절하지 않습니다. 상황에 맞는 메뉴에는 DataGridView에 대한 자체 이벤트가 있습니다. 행 컨텍스트 메뉴 및 셀 컨텍스트 메뉴에 대한 이벤트가 있습니다.
이 답변이 적절하지 않은 이유는 다른 운영 체계를 설명하지 않기 때문입니다. 접근성 옵션, 원격 연결 또는 Metro / Mono / Web / WPF 포팅이 작동하지 않을 수 있으며 바로 가기 키가 작동하지 않을 수 있습니다 (Shift + F10 또는 컨텍스트 메뉴 키).
마우스 오른쪽 버튼 클릭시 셀 선택은 수동으로 처리해야합니다. 컨텍스트 메뉴 표시는 UI에서 처리하므로 처리 할 필요가 없습니다.
이것은 Microsoft Excel에서 사용하는 접근 방식을 완전히 모방합니다. 셀이 선택한 범위의 일부인 경우 셀 선택은 변경되지 않으며 변경되지 않습니다 CurrentCell
. 그렇지 않으면 이전 범위가 지워지고 셀이 선택되고 CurrentCell
.
확실하지 않은 경우 CurrentCell
화살표 키를 눌렀을 때 키보드에 포커스가있는 위치입니다. Selected
의 일부인지 여부입니다 SelectedCells
. 컨텍스트 메뉴는 UI에서 처리하는대로 오른쪽 클릭시 표시됩니다.
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;
}
}
}
키보드 단축키는 기본적으로 컨텍스트 메뉴를 표시하지 않으므로 추가해야합니다.
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);
}
}
}
}
정적으로 작동하도록이 코드를 다시 작업 했으므로 모든 이벤트에 복사하여 붙여 넣을 수 있습니다.
핵심은 CellContextMenuStripNeeded
컨텍스트 메뉴를 제공하므로 사용 하는 것입니다.
다음은 CellContextMenuStripNeeded
행당 다른 메뉴를 사용하려는 경우 표시 할 컨텍스트 메뉴를 지정할 수있는 위치를 사용하는 예 입니다.
이러한 맥락에서 MultiSelect
이다 True
하고 SelectionMode
있다 FullRowSelect
. 이것은 단지 예를위한 것이며 제한이 아닙니다.
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
}
}
}