65.9K
CodeProject 正在变化。 阅读更多。
Home

将帮助集成到您的 .NET 应用程序中

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.66/5 (59投票s)

2004年4月12日

15分钟阅读

viewsIcon

327004

downloadIcon

5854

一篇关于如何利用 .NET 将帮助集成到您的应用程序中的文章。

引言

The .NET framework 为我们提供了 Help 类和 HelpProvider 组件,可以无缝地将帮助系统集成到我们的应用程序中。令人惊讶的是,尽管 .NET 文档中对使用 HelpProvider 组件将常规的、早已过时的帮助技术集成到您的应用程序中的说明不足。然而,自行学习起来并非难事。

"Windows Forms 的 HelpProvider 组件用于将 HTML Help 1.x 帮助文件(由 HTML Help Workshop 生成的 .chm 文件,或 .htm 文件)与您的 Windows 应用程序关联起来。HelpProvider 组件可用于为 Windows Forms 上的控件或特定控件提供上下文相关帮助。此外,HelpProvider 组件还可以打开帮助文件到特定区域,例如目录的主页、索引或搜索功能。"-MSDN

不可否认,在使用 VB6 时,帮助可能是我最不愿意集成到应用程序中的功能。即使是提供弹出式的上下文相关帮助窗口,也需要获得 Win32 API 的支持(获取足够的信息本身就很困难)。有了 .NET,我的这种倾向(以及任何可能同样懒惰的人的倾向)已经开始消失。现在提供弹出式窗口支持非常容易,我从 UI 构建的一开始就使用了它们。

.NET 立即允许您的帮助系统基于弹出窗口或/和在线/离线 HTML 方法。我最喜欢使用 .CHM 文件的方法,仅仅是因为它的关键字索引功能,如果不是其他原因的话。让我们面对现实吧。没有一种方法是没有缺点的。在线帮助可以使维护变得流畅而准确,但并非所有应用程序都要求用户连接到 Internet 来获得帮助。本文将演示如何使用 .NET 提供的功能来包含每种方法。请注意,关于如何使用 HTML Help Workshop 创建帮助文件的工具提示和背景信息将不在此讨论。

背景

HelpProvider 类

"为控件提供弹出式或在线帮助。……HelpProvider 的每个实例都维护一个指向与其关联的控件的引用集合。"-MSDN

HelpProvider 组件实现了非常特殊的 IExtenderProvider 接口,因此它能够为其他组件提供额外的属性。MSDN 对该接口有很好的描述,因此我建议求知欲强的读者自行查找。

可以从工具箱将 HelpProvider 组件拖到您的 Windows 窗体上。它很可能会自动命名为 HelpProvider1。我通常会将其更改为 hlpPrvMain 或其他更合适、更贴切的名称。在设计时唯一真正需要设置的属性是 HelpNamespace 属性,它包含一个字符串值,表示 HTML Help 源文件的路径。源文件可以是任何 .htm.chm 文件。但是,后来我发现它也可以指向 .txt 文件或任何文件,只是这样做的意义不大。唉!

扩展器属性

HelpProvider 组件可以毫不费力地与您的窗体及其上的所有控件整齐地关联起来。您可以通过查看属性窗口中每个控件突然出现的 HelpXXX 属性来确认这一点。我在某处读到,该组件为它向所有外部对象提供的每个属性维护一个单独的哈希表。添加的属性包括:-

  1. HelpButton

    此属性采用布尔值,决定帮助符号(?)是否出现在您的窗体的控件框中。但是,仅当窗体的 MaximizeBoxMinimizeBox 属性也设置为 false 时,该按钮才会出现。因此,帮助按钮通常仅在对话框窗体中可见。

  2. HelpNavigator

    指定一个常量,指示显示帮助文件中的哪些元素。它可以是 HelpNavigator Enum 中的任何一个值(如 MSDN 中所列):-

    表 1。

    成员名称 描述
    AssociateIndex 指定在指定 URL 中执行指定主题的索引。
    查找 指定显示指定 URL 的搜索页面。
    目录 指定显示指定 URL 的索引。
    KeywordIndex 指定要搜索的关键字以及在指定 URL 中要执行的操作。

    TableOfContents 指定显示指定 URL 的目录。
    主题 指定显示由指定 URL 引用的主题。
  3. HelpKeyword

    Help 关键字提供关键信息,用于从 HelpNamespace 指定的帮助文件中检索与此控件相关的帮助。它接受一个字符串值,该值对于 HelpNavigator 属性的不同值具有不同的含义。请参见下面的表 2。

    表 2。

    HelpNavigator 值 HelpKeyword 值代表什么。
    AssociateIndex 仅适用于 .chm 文件。将字符串值视为匹配标准,以在帮助索引中找到最简单的匹配项,这足以获得唯一命中。但不会显示主题。
    查找 仅适用于 .chm 文件。字符串值似乎被忽略,导致显示帮助文件的“查找”部分。
    目录 仅适用于 .chm 文件。将字符串值输入到“索引查找”文本框中,但不会显示相关主题。
    KeywordIndex 仅适用于 .chm 文件。字符串值不仅被输入到“索引查找”文本框中,而且还显示了相关主题。
    TableOfContents 仅适用于 .chm 文件。字符串值似乎被忽略,导致显示帮助文件的“内容”部分。
    主题 字符串值被视为文件名。该值可以选择性地包含锚点。例如,“index.htm#top”。
  4. HelpString

    HelpString 值代表当用户通过帮助按钮或按 F1 请求帮助时出现的弹出帮助窗口的帮助消息。

重要的公共成员

在设计时,您只能将 HelpProvider 的实例与一个帮助源关联。您的帮助源可以通过 HelpNamespace 属性设置,该属性接受一个字符串值,表示 .htm.chm 文件的路径。此属性是组件中唯一有用的属性。它用于包含帮助文件的名称,可以是 .htm.chm 文件(没有什么能阻止您提供文本文件甚至 .exe 文件的路径,但这并没有多大用处)。此外,它还公开了几个有用的方法:-

  1. SetHelpKeyword

    指定在用户调用指定控件的帮助时用于检索帮助的关键字。

    Overridable Public Sub SetHelpKeyword (ByVal ctl As Control, _
        ByVal keyword As String) 

    此字符串值用于在帮助文件中查找与指定控件相关的特定帮助部分。

  2. SetHelpNavigator

    指定在从指定控件的帮助文件中检索帮助时要使用的帮助命令。

    Overridable Public Sub SetHelpNavigator (ByVal ctl As Control, _
           ByVal navigator As HelpNavigator)

    此方法决定显示帮助文件的哪个元素。

  3. SetHelpString

    指定与指定控件关联的帮助字符串。

    Overridable Public Sub SetHelpString (ByVal ctl As Control, _
       ByVal helpString As String)

    此方法设置帮助字符串,但不显示弹出消息。当用户下次在控件上按 F1 时,将出现弹出窗口。

  4. SetShowHelp

    指定是否显示指定控件的帮助。

    Overridable Public Sub SetShowHelp (ByVal ctl As Control, _
           ByVal value As Boolean)

    此方法用于覆盖确定是否显示控件帮助的标志。

上面提到的 SetXXX 方法也有相关的 GetXXX 方法,如下所示:-

  1. GetHelpKeyword
  2. GetHelpNavigator
  3. GetHelpString
  4. GetShowHelp

HelpProvider 还会为每个控件的 HelpRequestedQueryAccessibilityHelp 事件注册事件处理程序。

Help 类

"封装了 HTML Help 1.0 引擎。……您可以使用 Help 对象显示已编译的帮助文件(.chm)或 HTML 帮助格式的 HTML 文件。已编译的帮助文件在页面中提供目录、索引、搜索和关键字链接。快捷方式仅在已编译的帮助文件中有效。您可以使用 HTML Help Workshop 生成 HTML Help 1.x 文件。"-MSDN

这是另一个文档很少的类。在 MSDN 上查找它,您会看到——“此成员支持 .NET Framework 基础结构,不打算直接从您的代码中使用”。尽管如此,请注意它位于 System.Windows.Forms 命名空间中,并用于从您的代码中显式显示帮助文件。它提供了两个有用的共享/静态方法供我们使用:-

  1. ShowHelp

    显示帮助文件的内容。

    显示指定 URL 的帮助文件内容

    Overloads Public Shared Sub ShowHelp(ByVal parent As Control, _
       ByVal url As String)

    显示指定 URL 处找到的帮助文件内容,用于特定主题

    Overloads Public Shared Sub ShowHelp(ByVal parent As Control, _
      ByVal url As String, ByVal navigator As HelpNavigator)

    显示指定 URL 处找到的帮助文件内容,用于特定关键字

    Overloads Public Shared Sub ShowHelp(ByVal parent As Control, _
       ByVal url As String,ByVal keyword As String)

    显示位于用户提供的 URL 中的帮助文件内容

    Overloads Public Shared Sub ShowHelp(ByVal parent As Control, _
      ByVal url As String, ByVal navigator As HelpNavigator, _
      ByVal param As Object)

    我从这个方法中学到了一个非常有趣的东西。它可以打开您提供给它的几乎任何 URL。URL 可以指向任何本地或远程资源。它甚至可以运行 EXE 文件,这是一个令人愉快的惊喜!确实很有趣!在需要额外参数的重载版本中,传入 Nothing,您会发现这些参数值被忽略了,或者至少它们不会干扰文件的运行。

  2. ShowHelpIndex

    显示帮助文件的索引或搜索窗口。

    Public Shared Sub ShowHelpIndex(ByVal parent As Control, _
        ByVal url As String)
  3. ShowPopUp

    在屏幕选定的位置显示弹出式帮助。

    Public Shared Sub ShowPopup( ByVal parent As Control, _
      ByVal caption As String, ByVal location As Point)

使用 HelpProvider 对象添加弹出式帮助

弹出式帮助涉及为控件或窗体提供上下文相关信息。帮助消息或信息嵌入在您的代码中。当用户在具有焦点的控件上按 F1 时,将显示上下文相关的弹出帮助消息。

一旦将 HelpProvider 组件添加到 Form 中,我们就可以为窗体上每个打算提供帮助的控件设置 HelpString。根据您使用的 HelpProvider 组件的数量,您会发现每个控件都有相同数量的 HelpString 属性,分别对应每个 HelpProvider 实例。将 HelpString 属性(对于您想用来提供弹出式帮助的 HelpProvider)设置为对每个控件有用的消息。确保 ShowHelp 属性(对应于同一个 HelpProvider 实例)对相关控件设置为 true。最好在同一窗体上使用单个 HelpProvider 来提供弹出式帮助,这样可以使维护更加容易。一旦在设计时设置了这两个属性,我们的工作就完成了!无需配置任何其他新可用属性。

同样的设计时配置也可以通过代码完成。但是,我们在设计时使用属性窗口为每个控件设置的属性在运行时不可用。相反,我们使用 HelpProvider 组件的 SetHelpString 方法,或者 Shared Help.ShowPopUp 方法,如下所示。

Help.ShowPopup(Me, _
  "Enter Phone number here. Valid input characters are 0-9,space,'-','(', and ')'", _
  Cursor.Position)

或者

'Setting the help string automatically enables 
'the pop-up display for the control.
hlpPopUp.SetHelpString(txtCity, _
  "You pressed F1 on the City field. How can I help you?")
'The following invocation is not necessary if you intend 
'to keep the pop-up enabled.
'However, the Pop-up display can be disabled for the control 
'if the second argument to this method takes a boolean False value. 
hlpPopUp.SetShowHelp(txtCity, True)

请参阅本文随附代码中的弹出式演示。

启用帮助按钮

帮助按钮(显示为“?”)出现在标题栏的右侧,如下图所示(图片来自我为本文准备的一些快速演示应用程序)。

您可以通过将其布尔值 HelpButton 属性设置为 True 来为您的窗体启用此按钮。使用此按钮的限制是,您必须去掉标题栏中的 MaximizeMinimize 框。因此,请继续将 MaximizeBoxMinimizeBox 属性设置为 False

在运行时单击帮助按钮会将光标更改为“?”。显示新光标后,单击您可能已设置 HelpString 属性的字段,弹出式帮助现在应该会显示。

请参阅本文随附代码中的弹出式演示。

HelpRequested 事件

每个控件(包括窗体)都会在其响应用户按下 F1 键时引发自己的 HelpRequested 事件。如果我们希望对过程进行更大的控制,那么在这里执行帮助调用实现是明智的。

示例

Private Sub txtPhone_HelpRequested(ByVal sender As Object, _
ByVal hlpevent As System.Windows.Forms.HelpEventArgs) _
Handles txtPhone.HelpRequested
Help.ShowPopup(Me, _
"Enter Phone number here. Valid input characters are 0-9", _
hlpevent.MousePos)
End Sub

但是,也可以通过侦听 KeyDown 或其他与键盘相关的事件来响应用户的帮助请求,只需筛选 KeyCode 值并在其等于 F1 键时执行必要的操作。请注意,HelpRequested 事件将在键盘事件之后无论如何都会触发。

'E.g.,
Private Sub txtPhone_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtPhone.KeyDown
If e.KeyCode = Keys.F1 Then
Help.ShowPopup(Me, _
"Enter Phone number here. Valid input characters are 0-9",Cursor.Position)
e.Handled = True
End If
End Sub

添加离线/在线 .Htm 帮助

使用 HelpProvider 类

第一步是将其 HelpNamespace 属性设置为有效的 URL。URL 将是离线网页的本地路径,或是在线网页的远程 URL(例如,“https://codeproject.org.cn”)。在设计时,您可以在 HelpProvider 组件的 HelpNamespace 属性中硬编码帮助资源的路径。

这样就足以在用户按下 F1 时在默认浏览器中显示页面。您实际上不需要更改任何其他属性。

要使用同一个 HelpProvider 组件为不同的上下文显示不同的网页,您必须通过编程方式将 HelpNamespace 属性值更改为适当的帮助资源。您可以在 HelpRequested 事件中进行更改。

'E.g.,
Private Sub lnkOpenHtmHelpIndex_HelpRequested(ByVal sender As Object, _
ByVal hlpevent As System.Windows.Forms.HelpEventArgs) _
Handles lnkOpenHtmHelpIndex.HelpRequested
    hlpPopUpAndHtm.HelpNamespace = IO.Path.GetDirectoryName(.HelpNamespace) & _
    "\help_on_city.htm"
End Sub

响应其他用户事件(例如单击事件)来打开帮助网页也很容易。请看下面

'E.g.,
Private Sub lnkOpenHtmHelpIndex_LinkClicked(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) _
Handles lnkOpenHtmHelpIndex.LinkClicked
    hlpPopUpAndHtm.HelpNamespace = IO.Path.GetDirectoryName(.HelpNamespace) & _
    "\help_on_city.htm"
    'To send F1 keystroke to the active application and 
    'get the help file displayed.
    SendKeys.Send("{F1}")
End Sub

请参阅本文随附代码中的帮助文件演示。

使用 Help 类

万一您想为同样的目的使用 System.Windows.Forms.Help 类,那么我们必须这样做:-

例如,

Help.ShowHelp(Me, "https://codeproject.org.cn")'A fab site

或者

Help.ShowHelp(Me, "\Help\index.htm") 'a path local to the client App.

请参阅本文随附代码中的帮助文件演示。

添加离线/在线 .chm 帮助

使用 HelpProvider 类

据我所闻,将 HelpProvider 组件与 .chm 文件关联是设计和集成 WinForms 应用程序帮助系统的首选方式,而且并非没有明显的原因。已编译的帮助文件在页面中提供目录、索引、搜索和关键字链接。

所以,首先!将组件的 HelpNamespace 属性设置为指向您的 .chm 帮助文件的有效 URL。.chm 文件通常位于客户端本地地址,但可能需要在 LAN 或 Internet 的远程位置找到该文件。无论如何,属性值都应符合您的需求。

完成此操作后,为(您希望与其关联帮助文件内容的)控件设置“ShowHelp On HelpProvider”为 true。选择一个合适的 HelpNavigator Enum 值,以便使用您的 HelpKeyword 值打开并查询帮助文件的所需部分。后者应包含您在帮助文件编译前包含的上下文特定关键字。它可以是编译文件的索引条目、搜索值或文件名。在每种情况下,HelpNavigator 的值都必须设置为如本文前面提供的表 2 所解释的特定值。

在设计时只需完成这些。

如果您想在运行时更改控件的 HelpKeyword 和/或 HelpNavigator 属性,请使用 HelpProvider 组件的 SetHelpKeyword 和/或 SetHelpNavigator 方法。

请参阅本文随附代码中的帮助文件演示。

使用 Help 类

Help 类也可以在运行时用于显示您的 .chm 文件的内容。

要显示目录,请执行类似以下操作

Help.ShowHelp(Me, "Help\VB.chm", HelpNavigator.TableOfContents)

更改 HelpNavigator Enum 值以显示帮助文件的其他部分。

如果您想显示索引部分,以下任一语句都可以完成工作

Help.ShowHelpIndex(Me, "Help\VB.chm")

或者

Help.ShowHelp(Me, "Help\VB.chm", HelpNavigator.KeywordIndex)

要显示已编译帮助源中的特定文件,请尝试以下操作

Help.ShowHelp(Me, "Help\VB.chm", "help_on_name.htm")

请参阅本文随附代码中的帮助文件演示。

将备用键关联到调用帮助

不一定非要将帮助仅与 F1 键关联。使用任何其他键或组合键启动帮助非常容易,但您需要为此提供代码。

例如,

Private Sub txtName_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) _
Handles txtName.KeyDown
    If e.KeyCode = Keys.F1 And e.Alt Then
    Help.ShowPopup(txtName, "This is an alternative help message", _
    New Point(Me.Location.X + txtName.Location.X, _
    Me.Location.Y + txtName.Location.Y))
    End If
End Sub

关注点

有趣的是,当您使用 Help.ShowHelp 方法调用网页(无论是本地还是远程)时,您是在一个外部进程中打开浏览器窗口。这意味着当您的客户端应用程序进程终止时,浏览器进程会保持运行,除非您之前已经关闭了它。如果调用它的应用程序关闭后,帮助文件仍然存在,这可能会让人尴尬。然而,使用 HelpProvider 组件打开的 .chm 文件则不会发生这种情况。

作为一种解决方法,我认为我们可以使用 System.Diagnostics 命名空间中的 Process 类的一个实例。以下是我为演示我的想法而设计的快速类。在实际使用之前,它可能并且应该被改进。

Namespace KingLeon
Public Class Help 
    Public Shared Function ShowHelp(ByVal url As String) _
    As System.Diagnostics.Process 
        Dim startInfo As New Diagnostics.ProcessStartInfo() 
        With startInfo 
        . FileName = url 
        .WindowStyle = ProcessWindowStyle.Normal 
        End With 
        Return System.Diagnostics.Process.Start(startInfo) 
    End Function 
    Public Shared Sub CloseHelp(ByVal proc As System.Diagnostics.Process) 
        If Not proc Is Nothing Then 
            If Not proc.HasExited Then proc.Kill()
        End If 
    End Sub 
End Class
End Namespace

KingLeon.Help.ShowHelp 方法是一个返回 Process 对象的函数。此 Process 对象可以存储在调用应用程序的集合中,以便以后引用,以防应用程序决定关闭。在这种情况下,我们将不得不遍历集合中的每个 Process 对象,并调用 KingLeon.Help.CloseHelp 方法,该方法以 Process 对象作为参数。我使用的集合是 ArrayList,我简单地将其评价为 .NET 提供的最好的东西之一。

'E.g.,
'Declare the collection to hold the process objects 
Private procList As New ArrayList()
........
........
........
Private Sub mnuItmOnlineHelp_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles mnuItmOnlineHelp.Click
    procList.Add(KingLeon.Help.ShowHelp("https://codeproject.org.cn"))
End Sub
........
........
........
Private Sub frmHelpFile_Closing(ByVal sender As Object, _
ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
    If Not procList Is Nothing Then
        Dim i As Integer
        For i = 0 To procList.Count - 1
            KingLeon.Help.CloseHelp(CType(procList(i), Diagnostics.Process))
        Next
    End If
End Sub

请参阅本文随附代码中的帮助文件演示。

使用代码

本文随附的代码提供了对本文讨论内容可能如何使用的简单演示。两个主要类是 frmHelpFile.vbfrmPopUp.vb。前者演示了如何与基于文件的帮助系统进行交互,而后者显示了基于弹出窗口的帮助可能多么有用。这样可以吗?

将帮助集成到您的 .NET 应用程序中 - CodeProject - 代码之家
© . All rights reserved.