按住 Alt 键时如何防止上下文菜单关闭?
How to prevent context menu from closing when holding the Alt key?
我需要允许 Alt
键在选择 ContextMenuStrip
中的某些菜单条目时用作修饰符。这适用于所有其他修饰符,如 Ctrl
或 Shift
。但是,出于某种原因 Alt
自动关闭上下文菜单。
我尝试使用上下文菜单中的 Closing
事件和菜单项 AutoClose
属性,但事实证明这比预期的更笨拙。具体来说,即使上下文菜单保持打开状态,应用程序 MenuStrip
也会被激活(这可以解释为什么上下文菜单首先关闭)。
我尝试四处搜索,但出乎意料的是,我发现的问题很少,而且 none 堆栈溢出,所以我想知道是否有更好的方法来解决我错过的这个问题?
显示抑制 MenuStrip
激活不会阻止上下文菜单关闭的示例代码:
class MainForm : Form
{
MenuStrip menuStrip;
ContextMenuStrip contextMenuStrip;
public MainForm()
{
KeyPreview = true;
menuStrip = new MenuStrip();
menuStrip.Items.Add("&File");
Controls.Add(menuStrip);
contextMenuStrip = new ContextMenuStrip();
contextMenuStrip.Items.Add("&OptionA");
contextMenuStrip.Items.Add("&OptionB");
ContextMenuStrip = contextMenuStrip;
}
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Alt)
{
e.Handled = true;
e.SuppressKeyPress = true;
}
else base.OnKeyDown(e);
}
}
这是设计使然,因此您必须自己进行状态跟踪。但这肯定会阻止 Alt
到达 MenuStrip
。
这是低级键盘过滤,因此当 Alt
完全由您自己按下时,您必须决定要做什么。
您还可以更改条件以检查 Alt
加上一些状态 。
简而言之,从 PreFilterMesssage
返回 true
将阻止它到达您的应用程序。
static void Main()
{
//...SNIP...
Application.AddMessageFilter(new AltFilter());
//...SNIP...
}
public class AltFilter : IMessageFilter
{
private static ushort WM_SYSKEYDOWN = 0x0104;
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == WM_SYSKEYDOWN && Control.ModifierKeys == Keys.Alt)
{
//Do your own special thing instead
return true;
}
return false;
}
}
我需要允许 Alt
键在选择 ContextMenuStrip
中的某些菜单条目时用作修饰符。这适用于所有其他修饰符,如 Ctrl
或 Shift
。但是,出于某种原因 Alt
自动关闭上下文菜单。
我尝试使用上下文菜单中的 Closing
事件和菜单项 AutoClose
属性,但事实证明这比预期的更笨拙。具体来说,即使上下文菜单保持打开状态,应用程序 MenuStrip
也会被激活(这可以解释为什么上下文菜单首先关闭)。
我尝试四处搜索,但出乎意料的是,我发现的问题很少,而且 none 堆栈溢出,所以我想知道是否有更好的方法来解决我错过的这个问题?
显示抑制 MenuStrip
激活不会阻止上下文菜单关闭的示例代码:
class MainForm : Form
{
MenuStrip menuStrip;
ContextMenuStrip contextMenuStrip;
public MainForm()
{
KeyPreview = true;
menuStrip = new MenuStrip();
menuStrip.Items.Add("&File");
Controls.Add(menuStrip);
contextMenuStrip = new ContextMenuStrip();
contextMenuStrip.Items.Add("&OptionA");
contextMenuStrip.Items.Add("&OptionB");
ContextMenuStrip = contextMenuStrip;
}
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Alt)
{
e.Handled = true;
e.SuppressKeyPress = true;
}
else base.OnKeyDown(e);
}
}
这是设计使然,因此您必须自己进行状态跟踪。但这肯定会阻止 Alt
到达 MenuStrip
。
这是低级键盘过滤,因此当 Alt
完全由您自己按下时,您必须决定要做什么。
您还可以更改条件以检查 Alt
加上一些状态 。
简而言之,从 PreFilterMesssage
返回 true
将阻止它到达您的应用程序。
static void Main()
{
//...SNIP...
Application.AddMessageFilter(new AltFilter());
//...SNIP...
}
public class AltFilter : IMessageFilter
{
private static ushort WM_SYSKEYDOWN = 0x0104;
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == WM_SYSKEYDOWN && Control.ModifierKeys == Keys.Alt)
{
//Do your own special thing instead
return true;
}
return false;
}
}