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

时间:2017-10-23 08:55:36

标签: c# .net winforms

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

我的问题是我无法弄清楚如何为菜单项做这件事。这些使用ToolStripMenuItem类,它不是从Control派生的,因此没有HelpKeyword属性。我应该如何为单个菜单项提供上下文相关帮助?谷歌先生并非即将到来。

1 个答案:

答案 0 :(得分:4)

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

我更喜欢使用上述解决方案之一,但为了学习目的,我将展示使用表单的HelpRequested事件可以做些什么。

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

在这里,您可以依靠Form事件来解决问题。由于您在表单上有HelpProvider,因此您应该知道HelpProvider在内部处理所有控件的HelpRequested事件,对于ShowHelp设置为true的控件,将Handled设置为true并阻止事件冒泡,以便在ShowHelptrue时,您无法使用自定义代码处理帮助事件。因此,您应将ShowHelp的控件设置为false,并使用HelpProvider作为帮助密钥持有者。

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

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

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

    1. 创建表单,菜单和控件 - 创建Form并在表单上放置一些控件和MenuStrip,其中包含一些菜单和子菜单。
    2. 配置HelpProvider - 在表单上放置HelpProvider控件,并为每个控件分配适当的键到HelpKeyword控件属性。同时将每个控件的ShowHelp设置为false。我们将处理代码帮助。
    3. 配置菜单帮助 - ToolStripMenuItem使用Tag属性存储帮助关键字。
    4. 创建辅助方法以查找菜单的后代 - 使用以下代码向您的应用程序添加类。在以下代码中,我介绍了一种扩展方法,以获取ToolStripMenuItem的所有子MenuStrip

      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();
          }
      }
      
    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);
      }
      
    6. 注意

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