Obwohl diese Frage alt ist, sind die Antworten nicht richtig. Kontextmenüs haben ihre eigenen Ereignisse in DataGridView. Es gibt ein Ereignis für das Zeilenkontextmenü und das Zellenkontextmenü.
Der Grund, warum diese Antworten nicht richtig sind, ist, dass sie keine unterschiedlichen Betriebsschemata berücksichtigen. Eingabehilfen, Remoteverbindungen oder Metro / Mono / Web / WPF-Portierung funktionieren möglicherweise nicht und Tastaturkürzel schlagen fehl (Umschalt + F10 oder Kontextmenütaste).
Die Zellenauswahl per Rechtsklick muss manuell erfolgen. Das Anzeigen des Kontextmenüs muss nicht behandelt werden, da dies von der Benutzeroberfläche erledigt wird.
Dies ahmt den von Microsoft Excel verwendeten Ansatz vollständig nach. Wenn eine Zelle Teil eines ausgewählten Bereichs ist, ändert sich die Zellenauswahl nicht und auch nicht CurrentCell
. Ist dies nicht der Fall, wird der alte Bereich gelöscht und die Zelle ausgewählt und wird CurrentCell
.
Wenn Sie sich nicht sicher sind, CurrentCell
hat die Tastatur beim Drücken der Pfeiltasten den Fokus. Selected
ist, ob es ein Teil von ist SelectedCells
. Das Kontextmenü wird beim Klicken mit der rechten Maustaste angezeigt, wie es von der Benutzeroberfläche verarbeitet wird.
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;
}
}
}
Tastaturkürzel zeigen standardmäßig nicht das Kontextmenü an, daher müssen wir sie hinzufügen.
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);
}
}
}
}
Ich habe diesen Code überarbeitet, damit er statisch funktioniert, sodass Sie ihn kopieren und in jedes Ereignis einfügen können.
Der Schlüssel ist zu verwenden, CellContextMenuStripNeeded
da dies Ihnen das Kontextmenü gibt.
In diesem Beispiel CellContextMenuStripNeeded
können Sie angeben, welches Kontextmenü angezeigt werden soll, wenn Sie unterschiedliche Zeilen pro Zeile verwenden möchten.
In diesem Zusammenhang MultiSelect
ist True
und SelectionMode
ist FullRowSelect
. Dies ist nur ein Beispiel und keine Einschränkung.
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
}
}
}