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






4.66/5 (59投票s)
2004年4月12日
15分钟阅读

327004

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
属性来确认这一点。我在某处读到,该组件为它向所有外部对象提供的每个属性维护一个单独的哈希表。添加的属性包括:-
HelpButton
此属性采用布尔值,决定帮助符号(?)是否出现在您的窗体的控件框中。但是,仅当窗体的
MaximizeBox
和MinimizeBox
属性也设置为 false 时,该按钮才会出现。因此,帮助按钮通常仅在对话框窗体中可见。HelpNavigator
指定一个常量,指示显示帮助文件中的哪些元素。它可以是
HelpNavigator
Enum
中的任何一个值(如 MSDN 中所列):-表 1。
成员名称 描述 AssociateIndex
指定在指定 URL 中执行指定主题的索引。 查找
指定显示指定 URL 的搜索页面。 目录
指定显示指定 URL 的索引。 KeywordIndex
指定要搜索的关键字以及在指定 URL 中要执行的操作。 TableOfContents
指定显示指定 URL 的目录。 主题
指定显示由指定 URL 引用的主题。 HelpKeyword
Help
关键字提供关键信息,用于从HelpNamespace
指定的帮助文件中检索与此控件相关的帮助。它接受一个字符串值,该值对于HelpNavigator
属性的不同值具有不同的含义。请参见下面的表 2。表 2。
HelpNavigator 值 HelpKeyword 值代表什么。 AssociateIndex
仅适用于 .chm 文件。将字符串值视为匹配标准,以在帮助索引中找到最简单的匹配项,这足以获得唯一命中。但不会显示主题。 查找
仅适用于 .chm 文件。字符串值似乎被忽略,导致显示帮助文件的“查找”部分。 目录
仅适用于 .chm 文件。将字符串值输入到“索引查找”文本框中,但不会显示相关主题。 KeywordIndex
仅适用于 .chm 文件。字符串值不仅被输入到“索引查找”文本框中,而且还显示了相关主题。 TableOfContents
仅适用于 .chm 文件。字符串值似乎被忽略,导致显示帮助文件的“内容”部分。 主题
字符串值被视为文件名。该值可以选择性地包含锚点。例如,“index.htm#top”。 HelpString
HelpString
值代表当用户通过帮助按钮或按 F1 请求帮助时出现的弹出帮助窗口的帮助消息。
重要的公共成员
在设计时,您只能将 HelpProvider
的实例与一个帮助源关联。您的帮助源可以通过 HelpNamespace
属性设置,该属性接受一个字符串值,表示 .htm 或 .chm 文件的路径。此属性是组件中唯一有用的属性。它用于包含帮助文件的名称,可以是 .htm 或 .chm 文件(没有什么能阻止您提供文本文件甚至 .exe 文件的路径,但这并没有多大用处)。此外,它还公开了几个有用的方法:-
SetHelpKeyword
指定在用户调用指定控件的帮助时用于检索帮助的关键字。
Overridable Public Sub SetHelpKeyword (ByVal ctl As Control, _ ByVal keyword As String)
此字符串值用于在帮助文件中查找与指定控件相关的特定帮助部分。
SetHelpNavigator
指定在从指定控件的帮助文件中检索帮助时要使用的帮助命令。
Overridable Public Sub SetHelpNavigator (ByVal ctl As Control, _ ByVal navigator As HelpNavigator)
此方法决定显示帮助文件的哪个元素。
SetHelpString
指定与指定控件关联的帮助字符串。
Overridable Public Sub SetHelpString (ByVal ctl As Control, _ ByVal helpString As String)
此方法设置帮助字符串,但不显示弹出消息。当用户下次在控件上按 F1 时,将出现弹出窗口。
SetShowHelp
指定是否显示指定控件的帮助。
Overridable Public Sub SetShowHelp (ByVal ctl As Control, _ ByVal value As Boolean)
此方法用于覆盖确定是否显示控件帮助的标志。
上面提到的 SetXXX
方法也有相关的 GetXXX
方法,如下所示:-
GetHelpKeyword
GetHelpNavigator
GetHelpString
GetShowHelp
HelpProvider
还会为每个控件的 HelpRequested
和 QueryAccessibilityHelp
事件注册事件处理程序。
Help 类
"封装了 HTML Help 1.0 引擎。……您可以使用
Help
对象显示已编译的帮助文件(.chm)或 HTML 帮助格式的 HTML 文件。已编译的帮助文件在页面中提供目录、索引、搜索和关键字链接。快捷方式仅在已编译的帮助文件中有效。您可以使用 HTML Help Workshop 生成 HTML Help 1.x 文件。"-MSDN
这是另一个文档很少的类。在 MSDN 上查找它,您会看到——“此成员支持 .NET Framework 基础结构,不打算直接从您的代码中使用”。尽管如此,请注意它位于 System.Windows.Forms
命名空间中,并用于从您的代码中显式显示帮助文件。它提供了两个有用的共享/静态方法供我们使用:-
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
,您会发现这些参数值被忽略了,或者至少它们不会干扰文件的运行。ShowHelpIndex
显示帮助文件的索引或搜索窗口。
Public Shared Sub ShowHelpIndex(ByVal parent As Control, _ ByVal url As String)
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
来为您的窗体启用此按钮。使用此按钮的限制是,您必须去掉标题栏中的 Maximize
和 Minimize
框。因此,请继续将 MaximizeBox
和 MinimizeBox
属性设置为 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.vb 和 frmPopUp.vb。前者演示了如何与基于文件的帮助系统进行交互,而后者显示了基于弹出窗口的帮助可能多么有用。这样可以吗?