Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Windows窗体中菜单项的上下文相关帮助_C#_.net_Winforms_Context Sensitive Help - Fatal编程技术网

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

C# Windows窗体中菜单项的上下文相关帮助,c#,.net,winforms,context-sensitive-help,C#,.net,Winforms,Context Sensitive Help,我正在为Visual Studio.NET中内置的现有WinForms应用程序实现上下文相关帮助。我在表单中添加了一个HelpProvider,并将HelpNamespace属性设置为一个奇妙的.chm,它覆盖了表单上的每个控件和菜单项。我已经在从控件派生的所有控件上设置了必要的HelpKeyword,到目前为止一切都很好:F1工作得非常完美 我的问题是,我不知道如何做它的菜单项。它们使用ToolStripMenuItem类,该类不是从控件派生的,因此没有HelpKeyword属性。如何为单个菜

我正在为Visual Studio.NET中内置的现有WinForms应用程序实现上下文相关帮助。我在表单中添加了一个HelpProvider,并将HelpNamespace属性设置为一个奇妙的.chm,它覆盖了表单上的每个控件和菜单项。我已经在从控件派生的所有控件上设置了必要的HelpKeyword,到目前为止一切都很好:F1工作得非常完美

我的问题是,我不知道如何做它的菜单项。它们使用ToolStripMenuItem类,该类不是从控件派生的,因此没有HelpKeyword属性。如何为单个菜单项提供上下文相关帮助?谷歌并不是很乐于助人。

使用F1并不是为菜单项提供帮助的常见方式。菜单项通常使用工具提示,或者在状态栏中显示一些帮助文本,或者它们的综合帮助通常与主页的帮助内容一起提供

我更喜欢使用上面提到的解决方案之一,但出于学习的目的,我将展示使用表单事件可以做什么

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

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

要使用表单的HelpRequested事件解决此问题,应遵循以下步骤:

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

下面是一个逐步示例,说明如何使用F1键显示菜单项的帮助。为此,请执行以下步骤:

创建窗体、菜单和控件-创建一个窗体,并在窗体上放置一些控件和具有一些菜单和子菜单的菜单。 配置HelpProvider-在窗体上放置HelpProvider控件,并为每个控件为控件的HelpKeyword属性分配合适的键。还将每个控件的ShowHelp设置为false。我们将在代码中处理帮助。 配置菜单帮助-对于ToolStripMenuItem,使用其标记属性存储帮助关键字。 创建一个helper方法来查找菜单的子体-向应用程序中添加一个具有以下代码的类。在以下代码中,我引入了一种扩展方法来获取MenuStrip的所有子ToolStripMenuItem:

为了测试解决方案,您不需要具有索引等的chm文件。您可以简单地在表单的文本属性中显示helpkeyword。这意味着解决方案正在运行,然后您可以创建合适的chm文件。 您可以根据需要使用类的ShowHelp方法的其他重载之一。 控件有HelpKeyword和HelpString扩展属性,请注意使用的是哪一个,并在HelpRequested事件中获得相同的属性。 不要忘记将ShowHelp设置为false。如果忘记此步骤,事件将在Helpprovider中进行内部处理。 不要忘记为菜单项的标记属性指定一个帮助关键字。为了使它对将来更加友好,您可以简单地创建一个扩展程序提供程序,将help关键字属性添加到菜单项中。 使用F1不是为菜单项提供帮助的常用方式。菜单项通常使用工具提示,或者在状态栏中显示一些帮助文本,或者它们的综合帮助通常与主页的帮助内容一起提供

我更喜欢使用上面提到的解决方案之一,但出于学习的目的,我将展示使用表单事件可以做什么

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

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

要使用表单的HelpRequested事件解决此问题,应遵循以下步骤:

对于ToolStripMenuItems,使用Tag属性作为帮助密钥持有者。 对于其他控件,如果使用HelpProvider分配HelpKey,请不要忘记将ShowHelp设置为false。 操纵直升机 这种形式的前传事件。 在事件处理程序的主体中,检查表单上是否有活动菜单项,然后使用活动项的Tag属性显示帮助。如果没有任何活动菜单,请使用窗体的ActiveControl属性显示帮助。 范例

下面是一个逐步示例,说明如何使用F1键显示菜单项的帮助。为此,请执行以下步骤:

创建窗体、菜单和控件-创建一个窗体,并在窗体上放置一些控件和具有一些菜单和子菜单的菜单。 配置HelpProvider-在窗体上放置HelpProvider控件,并为每个控件为控件的HelpKeyword属性分配合适的键。还将每个控件的ShowHelp设置为false。我们将在代码中处理帮助。 配置菜单帮助-对于ToolStripMenuItem,使用其标记属性存储帮助关键字。 创建一个helper方法来查找菜单的子体-向应用程序中添加一个具有以下代码的类。在以下代码中,我引入了一种扩展方法来获取MenuStrip的所有子ToolStripMenuItem:

为了测试解决方案,您不需要具有索引等的chm文件。您可以简单地在表单的文本属性中显示helpkeyword。这意味着解决方案正在运行,然后您可以创建合适的chm文件。 您可以根据需要使用类的ShowHelp方法的其他重载之一。 控件有HelpKeyword和HelpString扩展属性,请注意使用的是哪一个,并在HelpRequested事件中获得相同的属性。 不要忘记将ShowHelp设置为false。如果忘记此步骤,事件将在Helpprovider中进行内部处理。 不要忘记为菜单项的标记属性指定一个帮助关键字。为了使它对将来更加友好,您可以简单地创建一个扩展程序提供程序,将help关键字属性添加到菜单项中。
如果要使F1键适用于ToolStripMenuItem元素,则应依赖于表单的HelpRequested事件。此外,还应将所有控件的ShowHelp extended属性设置为false,并使用help类显示帮助。还应将菜单项的帮助关键字保留在其标记中或使用新的扩展程序提供程序。@RezaAghaei谢谢,但ToolStripMenuItem类没有HelpRequested事件。我想我可以使用为MenuStrip触发的HelpRequested事件,但需要确定从鼠标位置单击了哪个菜单项。在我看来,应该有一种更简单的方法,当然这是一种常见的做法?使用F1并不是为菜单项提供帮助的常见方法。菜单项通常使用工具提示,或者在状态栏中显示一些文本帮助,或者它们的综合帮助通常来自主页面的帮助。如果要使F1键适用于ToolStripMenuItem元素,则应依赖窗体的HelpRequested事件。此外,还应将所有控件的ShowHelp extended属性设置为false,并使用help类显示帮助。还应将菜单项的帮助关键字保留在其标记中或使用新的扩展程序提供程序。@RezaAghaei谢谢,但ToolStripMenuItem类没有HelpRequested事件。我想我可以使用为MenuStrip触发的HelpRequested事件,但需要确定从鼠标位置单击了哪个菜单项。在我看来,应该有一种更简单的方法,当然这是一种常见的做法?使用F1并不是为菜单项提供帮助的常见方法。菜单项通常使用工具提示,或者在状态栏中显示一些文本帮助,或者它们的全面帮助通常来自主页的帮助。哇,感谢您的努力!我只是在尝试确定在事件处理程序中选择了哪个菜单项,您为我节省了一些时间。我也没有意识到关闭ShowHelp属性是在HelpProvider存在时触发HelpRequested事件的原因。我可以确认这对我的使用有一些调整。顺便说一句,帮助文件已经由我们的文档组编写,它有一些漂亮的图形等,这就是为什么我不想使用纯文本工具提示或状态栏。再次感谢:-@JonP太好了!不客气,谢谢你的编辑:哇,谢谢你的努力!我只是在尝试确定在事件处理程序中选择了哪个菜单项,您为我节省了一些时间。我也没有意识到关闭ShowHelp属性是在HelpProvider存在时触发HelpRequested事件的原因。我可以确认这对我的使用有一些调整。顺便说一句,帮助文件已经由我们的文档组编写,它有一些漂亮的图形等,这就是为什么我不想使用纯文本工具提示或状态栏。再次感谢:-@JonP太好了!欢迎并感谢您的编辑:
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();
    }
}
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);
}