C# Keys.Apps 将始终打开 Windows 上下文菜单
C# Keys.Apps will always open Windows context menu
我正在尝试处理键盘上的 Apps/Context 菜单键。键应在 TextBox 处捕获,然后应显示 DataGridView 对象的已编程 ContextMenuStrip。
然而,显示 ContextMenuStrip 却非常简单。我唯一的问题是标志 e.Handled = true
似乎无法阻止 TextBox 的 Windows 默认上下文菜单出现。因此它打开 DataGridView 的 ContextMenuStrip 和 TextBox 的默认上下文菜单。
以下代码适用:
void EditSearchField_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Apps)
{
// ContextMenuStrip is shown here
DataGridView1.ContextMenuStrip.Show(DataGridView1, new Point(0, 0));
e.Handled = true;
e.SuppressKeyPress = true;
}
}
结果看起来很不愉快。 KeyPreview = true
也已设置。
有什么想法吗?
由于 ProcessCmdKey()
和 PreviewKeyDown()
没有完成这项工作,我决定采用另一种方法...
我为我的问题找到了一个(至少满足我的需要)不错的解决方法。在我的表单的 "designer" 部分,我为我的 TextBox 定义了一个新的 ContextMenuStrip:
// editSearchField
[...]
this.editSearchField.ContextMenuStrip = new System.Windows.Forms.ContextMenuStrip();
这导致 Windows 默认上下文菜单不再显示。由于 ContextMenuStrip 没有 ToolStripMenuItems,它会立即被丢弃。
为了完整起见,下面是我如何更改 KeyDown()
函数
void EditSearchField_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Apps)
{
if (dgvClients.SelectedRows.Count > 0)
{
// force the selected row to be visible, or else we could get a .NET debugger
dgvClients.CurrentCell = dgvClients.SelectedRows[0].Cells[0];
// prepare context menu (disable inaccessible entries)
Point ptMouse = dgvClients.GetCellDisplayRectangle(0, dgvClients.SelectedRows[0].Index, false).Location;
var mouseEvtArgs = new MouseEventArgs(MouseButtons.Right, 1, 0, 0, 0);
var mouseDgvArgs = new DataGridViewCellMouseEventArgs(0, dgvClients.SelectedRows[0].Index, ptMouse.X, ptMouse.Y, mouseEvtArgs);
DgvClientsMouseDown(dgvClients, mouseDgvArgs);
// calculate location for the context menu and finally show it
Point ptContextMenuPos = dgvClients.PointToScreen(ptMouse);
ptContextMenuPos.X += dgvClients.Width / 2;
ptContextMenuPos.Y += dgvClients.RowTemplate.Height / 2;
dgvClients.ContextMenuStrip.Show(ptContextMenuPos);
}
e.Handled = true;
e.SuppressKeyPress = true;
}
}
编辑: 修复了代码中的一个错误
我正在尝试处理键盘上的 Apps/Context 菜单键。键应在 TextBox 处捕获,然后应显示 DataGridView 对象的已编程 ContextMenuStrip。
然而,显示 ContextMenuStrip 却非常简单。我唯一的问题是标志 e.Handled = true
似乎无法阻止 TextBox 的 Windows 默认上下文菜单出现。因此它打开 DataGridView 的 ContextMenuStrip 和 TextBox 的默认上下文菜单。
以下代码适用:
void EditSearchField_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Apps)
{
// ContextMenuStrip is shown here
DataGridView1.ContextMenuStrip.Show(DataGridView1, new Point(0, 0));
e.Handled = true;
e.SuppressKeyPress = true;
}
}
结果看起来很不愉快。 KeyPreview = true
也已设置。
有什么想法吗?
由于 ProcessCmdKey()
和 PreviewKeyDown()
没有完成这项工作,我决定采用另一种方法...
我为我的问题找到了一个(至少满足我的需要)不错的解决方法。在我的表单的 "designer" 部分,我为我的 TextBox 定义了一个新的 ContextMenuStrip:
// editSearchField
[...]
this.editSearchField.ContextMenuStrip = new System.Windows.Forms.ContextMenuStrip();
这导致 Windows 默认上下文菜单不再显示。由于 ContextMenuStrip 没有 ToolStripMenuItems,它会立即被丢弃。
为了完整起见,下面是我如何更改 KeyDown()
函数
void EditSearchField_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Apps)
{
if (dgvClients.SelectedRows.Count > 0)
{
// force the selected row to be visible, or else we could get a .NET debugger
dgvClients.CurrentCell = dgvClients.SelectedRows[0].Cells[0];
// prepare context menu (disable inaccessible entries)
Point ptMouse = dgvClients.GetCellDisplayRectangle(0, dgvClients.SelectedRows[0].Index, false).Location;
var mouseEvtArgs = new MouseEventArgs(MouseButtons.Right, 1, 0, 0, 0);
var mouseDgvArgs = new DataGridViewCellMouseEventArgs(0, dgvClients.SelectedRows[0].Index, ptMouse.X, ptMouse.Y, mouseEvtArgs);
DgvClientsMouseDown(dgvClients, mouseDgvArgs);
// calculate location for the context menu and finally show it
Point ptContextMenuPos = dgvClients.PointToScreen(ptMouse);
ptContextMenuPos.X += dgvClients.Width / 2;
ptContextMenuPos.Y += dgvClients.RowTemplate.Height / 2;
dgvClients.ContextMenuStrip.Show(ptContextMenuPos);
}
e.Handled = true;
e.SuppressKeyPress = true;
}
}
编辑: 修复了代码中的一个错误