Windows 窗体中菜单项的上下文相关帮助

Jon*_*onP 1 .net c# winforms context-sensitive-help

我正在为在 Visual Studio .NET 中构建的现有 WinForms 应用程序实现上下文相关帮助。我HelpProvider在表单中添加了 a并将HelpNamespace属性设置为一个美妙的.chm,涵盖表单上的每个控件和菜单项。我已经设置了HelpKeyword所有衍生自的必要控件,Control到目前为止一切都很好:F1 完美运行。

我的问题是我不知道如何为菜单项做到这一点。它们使用ToolStripMenuItem类,该类不派生自Control,因此没有HelpKeyword属性。我应该如何为单个菜单项提供上下文相关的帮助?谷歌先生一直不太热情。

Rez*_*aei 5

使用F1不是为菜单项提供帮助的常用方法。菜单项通常使用ToolTip,或者在StatusBar 中显示一些帮助文本,或者它们的综合帮助通常带有主页的帮助内容

我更喜欢使用上述解决方案之一,但在这里出于学习目的,我将展示您可以使用HelpRequested表单的事件做什么。

要处理窗体和控件的帮助,您可以依赖HelpRequested窗体和控件的事件。

在这里你可以依靠Form事件来解决问题。由于您有一个HelpProvideron 表单,您应该知道在内部HelpProvider处理HelpRequested所有控件的事件,并且对于ShowHelp设置为 的控件true,它设置Handledtrue并防止事件冒泡,因此您无法使用自定义代码来处理帮助事件 if ShowHelpis true。因此,您应该将ShowHelp控件设置为false仅用HelpProvider作帮助密钥持有者。

要使用HelpRequested表单的事件解决问题,您应该按照以下步骤操作:

  1. 对于ToolStripMenuItems,使用该Tag属性作为帮助密钥持有者。
  2. 对于其他控件,如果使用HelpProvider了assign HelpKey,不要忘记设置ShowHelpfalse
  3. 处理HelpRequested表单的事件。
  4. 在事件处理程序的主体中,检查表单上是否有活动菜单项,然后使用Tag活动项的属性显示帮助。如果没有任何活动菜单,请使用ActiveControl表单的属性来显示帮助。

例子

这是一个分步示例,说明如何使用F1键显示菜单项的帮助。为此,请按照下列步骤操作:

  1. 创建窗体、菜单和控件- 创建一个FormMenuStrip在窗体上放置一些控件和一些菜单和子菜单。
  2. 配置 HelpProvider -HelpProvider在表单上放置一个控件,并为每个控件为控件HelpKeyword属性分配合适的键。还将ShowHelp每个控件设置为 false。我们将处理代码方面的帮助。
  3. 为菜单配置帮助- 用于ToolStripMenuItem使用其Tag属性来存储帮助关键字。
  4. 创建一个帮助方法来查找 Menu 的后代- 将一个类添加到您的应用程序中,该类具有以下代码。在下面的代码,我介绍了一个扩展方法来获取所有子ToolStripMenuItemMenuStrip

    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    public static class ToolStripMenuItemExtensions
    {
        public static List<ToolStripMenuItem> Descendants(this MenuStrip menu)
        {
            var items = menu.Items.OfType<ToolStripMenuItem>().ToList();
            return items.SelectMany(x => Descendants(x)).Concat(items).ToList();
        }
        public static List<ToolStripMenuItem> Descendants(this ToolStripMenuItem item)
        {
            var items = item.DropDownItems.OfType<ToolStripMenuItem>().ToList();
            return items.SelectMany(x => Descendants(x)).Concat(items).ToList();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 处理 Helprequested 事件以显示帮助- 处理HelpRequested表单事件并使用以下代码实现我上面描述的算法:

    private void Form1_HelpRequested(object sender, HelpEventArgs hlpevent)
    {
        string keyword = "";
    
        var selectedMenuItem = this.menuStrip1.Descendants()
            .Where(x => x.Selected).FirstOrDefault();
        if (selectedMenuItem != null)
            keyword = selectedMenuItem.Tag?.ToString();
        else if (ActiveControl != null)
            keyword = helpProvider1.GetHelpKeyword(ActiveControl);
    
        if (!string.IsNullOrEmpty(keyword))
            Help.ShowHelp(this, "Help.chm", HelpNavigator.Index, keyword);
    }
    
    Run Code Online (Sandbox Code Playgroud)

笔记

  • 为了测试解决方案,您不需要具有索引等的 chm 文件。您可以简单地在表单Text属性中显示 helpkeyword 。这意味着解决方案正在运行,之后您可以创建合适的 chm 文件。
  • 您可以根据需要使用类ShowHelp方法的其他重载之一Help
  • HelpKeywordHelpString扩展属性的控件,您正在使用,并得到在同一个哪一个要注意HelpRequested的事件。
  • 不要忘记设置ShowHelp为false。如果忘记这一步,事件将在Helpprovider.
  • 不要忘记为Tag菜单项的属性分配帮助关键字。为了使其对未来更加友好,您可以简单地创建一个扩展程序提供程序,为菜单项添加帮助关键字属性。