突出显示菜单项时的事件
Event when a menu item is highlighted
有没有人想出只要突出显示菜单项就会触发的事件?
我想在状态栏中突出显示每个菜单命令的说明。无论是使用鼠标还是键盘突出显示它们,我都希望发生这种情况。
但是经过相当大的努力,我没有看到这样的事件。我什至尝试覆盖 WndProc
来检测原始菜单消息,但发现 none 已发送。显然,WinForms 不使用标准的 Windows 菜单。
看来知道菜单项何时被点击和何时被选中(突出显示而不被点击)应该是两个最重要的菜单事件。不知道为什么不支持后者
有人能解决这个问题吗?
在@dr.null 的帮助下,我成功了。这是我的代码版本。
private void InitializeMenuStatus(ToolStrip toolStrip)
{
toolStrip.ShowItemToolTips = false;
toolStrip.KeyUp += ToolStrip_KeyUp;
foreach (ToolStripItem toolStripItem in toolStrip.Items)
{
toolStripItem.AutoToolTip = false;
toolStripItem.MouseEnter += ToolStripItem_MouseEnter;
toolStripItem.MouseLeave += ToolStripItem_MouseLeave;
if (toolStripItem is ToolStripDropDownItem dropDownItem)
InitializeMenuStatus(dropDownItem.DropDown);
}
}
private ToolStripItem? SelectedMenuItem = null;
private void SetSelectedMenuItem(ToolStripItem? item)
{
if (!ReferenceEquals(item, SelectedMenuItem))
{
SelectedMenuItem = item;
lblStatus.Text = item?.ToolTipText ?? string.Empty;
}
}
private void ToolStripItem_MouseEnter(object? sender, EventArgs e)
{
if (sender is ToolStripMenuItem menuItem && menuItem.Selected)
SetSelectedMenuItem(menuItem);
}
private void ToolStripItem_MouseLeave(object? sender, EventArgs e)
{
SetSelectedMenuItem(null);
}
private void ToolStrip_KeyUp(object? sender, KeyEventArgs e)
{
if (sender is ToolStripDropDownMenu dropDownMenu)
{
ToolStripMenuItem? menuItem = dropDownMenu.Items.OfType<ToolStripMenuItem>()
.Where(m => m.Selected)
.FirstOrDefault();
SetSelectedMenuItem(menuItem);
}
}
为什么从未将 Selected
事件添加到菜单项使我不解。我有 suggested that it be added。如果您同意,请去表示您对该请求的支持。
如果有人感兴趣,我花了一些时间微调这段代码并最终制作了一个免费组件,现在作为 NuGet 包发布。您可以在GitHub
上查看代码
除了鼠标事件,您还可以通过处理所有者菜单的 KeyUp
事件来添加键盘按键部分,以获取所选项目并在状态栏标签中显示描述。
public YourForm()
{
InitializeComponent();
menuStrip1.ShowItemToolTips = false;
menuStrip1.KeyUp += OnToolStripKeyUp;
foreach (var item in GetAllToolStripItems(menuStrip1.Items))
{
item.AutoToolTip = false;
item.MouseEnter += OnToolStripItemMouseEnter;
item.MouseLeave += OnToolStripItemMouseLeave;
if (item.GetCurrentParent() is ToolStrip dm)
{
dm.ShowItemToolTips = false;
dm.KeyUp -= OnToolStripKeyUp;
dm.KeyUp += OnToolStripKeyUp;
}
}
}
private void OnToolStripItemMouseEnter(object sender, EventArgs e)
{
sbrLabel.Text = (sender as ToolStripItem).ToolTipText;
}
private void OnToolStripItemMouseLeave(object sender, EventArgs e)
{
sbrLabel.Text = "Ready";
}
private void OnToolStripKeyUp(object sender, KeyEventArgs e)
{
var s = sender as ToolStrip;
var selItem = s.Items.OfType<ToolStripMenuItem>().FirstOrDefault(x => x.Selected);
sbrLabel.Text = selItem?.ToolTipText;
}
private IEnumerable<ToolStripItem> GetAllToolStripItems(ToolStripItemCollection tsic)
{
foreach (var tsi in tsic.Cast<ToolStripItem>())
{
yield return tsi;
if (tsi is ToolStripDropDownItem tsddi && tsddi.HasDropDown)
foreach (var ddi in GetAllToolStripItems(tsddi.DropDownItems))
yield return ddi;
}
}
有没有人想出只要突出显示菜单项就会触发的事件?
我想在状态栏中突出显示每个菜单命令的说明。无论是使用鼠标还是键盘突出显示它们,我都希望发生这种情况。
但是经过相当大的努力,我没有看到这样的事件。我什至尝试覆盖 WndProc
来检测原始菜单消息,但发现 none 已发送。显然,WinForms 不使用标准的 Windows 菜单。
看来知道菜单项何时被点击和何时被选中(突出显示而不被点击)应该是两个最重要的菜单事件。不知道为什么不支持后者
有人能解决这个问题吗?
在@dr.null 的帮助下,我成功了。这是我的代码版本。
private void InitializeMenuStatus(ToolStrip toolStrip)
{
toolStrip.ShowItemToolTips = false;
toolStrip.KeyUp += ToolStrip_KeyUp;
foreach (ToolStripItem toolStripItem in toolStrip.Items)
{
toolStripItem.AutoToolTip = false;
toolStripItem.MouseEnter += ToolStripItem_MouseEnter;
toolStripItem.MouseLeave += ToolStripItem_MouseLeave;
if (toolStripItem is ToolStripDropDownItem dropDownItem)
InitializeMenuStatus(dropDownItem.DropDown);
}
}
private ToolStripItem? SelectedMenuItem = null;
private void SetSelectedMenuItem(ToolStripItem? item)
{
if (!ReferenceEquals(item, SelectedMenuItem))
{
SelectedMenuItem = item;
lblStatus.Text = item?.ToolTipText ?? string.Empty;
}
}
private void ToolStripItem_MouseEnter(object? sender, EventArgs e)
{
if (sender is ToolStripMenuItem menuItem && menuItem.Selected)
SetSelectedMenuItem(menuItem);
}
private void ToolStripItem_MouseLeave(object? sender, EventArgs e)
{
SetSelectedMenuItem(null);
}
private void ToolStrip_KeyUp(object? sender, KeyEventArgs e)
{
if (sender is ToolStripDropDownMenu dropDownMenu)
{
ToolStripMenuItem? menuItem = dropDownMenu.Items.OfType<ToolStripMenuItem>()
.Where(m => m.Selected)
.FirstOrDefault();
SetSelectedMenuItem(menuItem);
}
}
为什么从未将 Selected
事件添加到菜单项使我不解。我有 suggested that it be added。如果您同意,请去表示您对该请求的支持。
如果有人感兴趣,我花了一些时间微调这段代码并最终制作了一个免费组件,现在作为 NuGet 包发布。您可以在GitHub
上查看代码除了鼠标事件,您还可以通过处理所有者菜单的 KeyUp
事件来添加键盘按键部分,以获取所选项目并在状态栏标签中显示描述。
public YourForm()
{
InitializeComponent();
menuStrip1.ShowItemToolTips = false;
menuStrip1.KeyUp += OnToolStripKeyUp;
foreach (var item in GetAllToolStripItems(menuStrip1.Items))
{
item.AutoToolTip = false;
item.MouseEnter += OnToolStripItemMouseEnter;
item.MouseLeave += OnToolStripItemMouseLeave;
if (item.GetCurrentParent() is ToolStrip dm)
{
dm.ShowItemToolTips = false;
dm.KeyUp -= OnToolStripKeyUp;
dm.KeyUp += OnToolStripKeyUp;
}
}
}
private void OnToolStripItemMouseEnter(object sender, EventArgs e)
{
sbrLabel.Text = (sender as ToolStripItem).ToolTipText;
}
private void OnToolStripItemMouseLeave(object sender, EventArgs e)
{
sbrLabel.Text = "Ready";
}
private void OnToolStripKeyUp(object sender, KeyEventArgs e)
{
var s = sender as ToolStrip;
var selItem = s.Items.OfType<ToolStripMenuItem>().FirstOrDefault(x => x.Selected);
sbrLabel.Text = selItem?.ToolTipText;
}
private IEnumerable<ToolStripItem> GetAllToolStripItems(ToolStripItemCollection tsic)
{
foreach (var tsi in tsic.Cast<ToolStripItem>())
{
yield return tsi;
if (tsi is ToolStripDropDownItem tsddi && tsddi.HasDropDown)
foreach (var ddi in GetAllToolStripItems(tsddi.DropDownItems))
yield return ddi;
}
}