突出显示菜单项时的事件

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;
    }
}