Windows 表单中菜单项的上下文相关帮助
Context-sensitive help for menu items in Windows Forms
我正在为 Visual Studio .NET 中内置的现有 WinForms 应用程序实施上下文相关帮助。我在表单中添加了一个 HelpProvider
并将 HelpNamespace
属性 设置为一个很棒的 .chm
,它涵盖了表单上的每个控件和菜单项。我已经在派生自 Control
的所有控件上设置了必要的 HelpKeyword
,到目前为止一切都很好:F1 完美运行。
我的问题是我不知道如何为菜单项执行此操作。这些使用 ToolStripMenuItem
class,它不是从 Control
派生的,因此没有 HelpKeyword
属性。我应该如何为单个菜单项提供上下文相关的帮助? Google 先生不太热情。
使用 F1 不是为菜单项提供帮助的常用方法。菜单项通常使用 ToolTip,或者在 StatusBar 中显示一些帮助文本,或者通常它们的综合帮助带有 主页的帮助内容.
我更喜欢使用上述解决方案之一,但出于学习目的,我将展示您可以使用表单的 HelpRequested
事件做什么。
要处理表单和控件的帮助,您可以依赖表单和控件的 HelpRequested
事件。
这里可以依靠Form
事件来解决问题。由于您在表单上有一个 HelpProvider
,您应该知道 HelpProvider
在内部处理所有控件的 HelpRequested
事件,并且对于 ShowHelp
设置为 true
的控件,它将 Handled
设置为 true
并防止事件冒泡,因此如果 ShowHelp
为 true
,您将无法使用自定义代码来处理帮助事件。因此,您应该将控件的 ShowHelp
设置为 false
并仅使用 HelpProvider
作为帮助密钥持有者。
要解决使用表单的 HelpRequested
事件的问题,您应该按照以下步骤操作:
- 对于
ToolStripMenuItems
,使用 Tag
属性 作为帮助密钥持有者。
- 对于其他控件,如果使用
HelpProvider
分配HelpKey
,不要忘记将ShowHelp
设置为false
。
- 处理表单的
HelpRequested
事件。
- 在事件处理程序的主体中,检查您的表单上是否有活动菜单项,然后使用活动项目的
Tag
属性 显示帮助。如果没有任何活动菜单,请使用表格的 ActiveControl
属性 显示帮助。
例子
这是一个逐步示例,说明如何使用 F1 键显示菜单项的帮助。为此,请按照下列步骤操作:
- 创建窗体、菜单和控件 - 创建一个
Form
并在窗体上放置一些控件和一个具有一些菜单和子菜单的 MenuStrip
。
- 配置 HelpProvider - 在表单上放置一个
HelpProvider
控件,并为每个控件分配合适的键到 HelpKeyword
属性 控件。同时将每个控件的 ShowHelp
设置为 false。我们将在代码中处理帮助。
- 为菜单配置帮助 - 对于
ToolStripMenuItem
使用其 Tag
属性 来存储帮助关键字。
创建辅助方法以查找菜单的后代 - 添加一个 class 到具有以下代码的应用程序。在下面的代码中,我引入了一种扩展方法来获取 MenuStrip
:
的所有子 ToolStripMenuItem
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();
}
}
Handling the Helprequested event to show help - 处理表单的 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);
}
注意
- 为了测试解决方案,您不需要具有索引等的 chm 文件。您可以简单地以
Text
属性 形式显示帮助关键字。这意味着解决方案正在运行,之后您可以创建合适的 chm 文件。
- 您可以根据需要使用
Help
class 的 ShowHelp
方法的其他重载之一。
- 控件有
HelpKeyword
和HelpString
扩展属性,注意你用的是哪一个,在HelpRequested
事件中获取相同的。
- 不要忘记将
ShowHelp
设置为 false。如果您忘记了这一步,事件将在 Helpprovider
. 内部处理
- 不要忘记为
Tag
属性 个菜单项分配帮助关键字。为了使其对未来更友好,您可以简单地创建一个扩展程序提供程序,将帮助关键字 属性 添加到菜单项。
我正在为 Visual Studio .NET 中内置的现有 WinForms 应用程序实施上下文相关帮助。我在表单中添加了一个 HelpProvider
并将 HelpNamespace
属性 设置为一个很棒的 .chm
,它涵盖了表单上的每个控件和菜单项。我已经在派生自 Control
的所有控件上设置了必要的 HelpKeyword
,到目前为止一切都很好:F1 完美运行。
我的问题是我不知道如何为菜单项执行此操作。这些使用 ToolStripMenuItem
class,它不是从 Control
派生的,因此没有 HelpKeyword
属性。我应该如何为单个菜单项提供上下文相关的帮助? Google 先生不太热情。
使用 F1 不是为菜单项提供帮助的常用方法。菜单项通常使用 ToolTip,或者在 StatusBar 中显示一些帮助文本,或者通常它们的综合帮助带有 主页的帮助内容.
我更喜欢使用上述解决方案之一,但出于学习目的,我将展示您可以使用表单的 HelpRequested
事件做什么。
要处理表单和控件的帮助,您可以依赖表单和控件的 HelpRequested
事件。
这里可以依靠Form
事件来解决问题。由于您在表单上有一个 HelpProvider
,您应该知道 HelpProvider
在内部处理所有控件的 HelpRequested
事件,并且对于 ShowHelp
设置为 true
的控件,它将 Handled
设置为 true
并防止事件冒泡,因此如果 ShowHelp
为 true
,您将无法使用自定义代码来处理帮助事件。因此,您应该将控件的 ShowHelp
设置为 false
并仅使用 HelpProvider
作为帮助密钥持有者。
要解决使用表单的 HelpRequested
事件的问题,您应该按照以下步骤操作:
- 对于
ToolStripMenuItems
,使用Tag
属性 作为帮助密钥持有者。 - 对于其他控件,如果使用
HelpProvider
分配HelpKey
,不要忘记将ShowHelp
设置为false
。 - 处理表单的
HelpRequested
事件。 - 在事件处理程序的主体中,检查您的表单上是否有活动菜单项,然后使用活动项目的
Tag
属性 显示帮助。如果没有任何活动菜单,请使用表格的ActiveControl
属性 显示帮助。
例子
这是一个逐步示例,说明如何使用 F1 键显示菜单项的帮助。为此,请按照下列步骤操作:
- 创建窗体、菜单和控件 - 创建一个
Form
并在窗体上放置一些控件和一个具有一些菜单和子菜单的MenuStrip
。 - 配置 HelpProvider - 在表单上放置一个
HelpProvider
控件,并为每个控件分配合适的键到HelpKeyword
属性 控件。同时将每个控件的ShowHelp
设置为 false。我们将在代码中处理帮助。 - 为菜单配置帮助 - 对于
ToolStripMenuItem
使用其Tag
属性 来存储帮助关键字。 创建辅助方法以查找菜单的后代 - 添加一个 class 到具有以下代码的应用程序。在下面的代码中,我引入了一种扩展方法来获取
的所有子MenuStrip
:ToolStripMenuItem
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(); } }
Handling the Helprequested event to show help - 处理表单的
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); }
注意
- 为了测试解决方案,您不需要具有索引等的 chm 文件。您可以简单地以
Text
属性 形式显示帮助关键字。这意味着解决方案正在运行,之后您可以创建合适的 chm 文件。 - 您可以根据需要使用
Help
class 的ShowHelp
方法的其他重载之一。 - 控件有
HelpKeyword
和HelpString
扩展属性,注意你用的是哪一个,在HelpRequested
事件中获取相同的。 - 不要忘记将
ShowHelp
设置为 false。如果您忘记了这一步,事件将在Helpprovider
. 内部处理
- 不要忘记为
Tag
属性 个菜单项分配帮助关键字。为了使其对未来更友好,您可以简单地创建一个扩展程序提供程序,将帮助关键字 属性 添加到菜单项。