WPF中F1帮助文档的打开

      最近在看帮助文档实现部分,前面看了一下C#里面有个HelpProvider类用于实现帮助文档,但是后来发现WPF里面居然没有这个控件,甚是郁闷,所以就在网上找找,下面就是所有的相关网页,内容不多,主要就是以下两个例子:

 

      第一个例子,只有一篇文章介绍,也没有看到别人转载:

      http://blogs.windowsclient.net/bragi/archive/2008/04/08/html-help-from-within-wpf-applications.aspx

      作者写了个dll,感觉功能并没有多少,但是dll工程中的类比较多,也挺大,所以没有仔细研究。

 

 

      第二个例子,这个应该是最佳解决方案,有几个文章提到了,方法一样,只是侧重点稍有不同,结合起来可以看得更全面些,下面是找到:

 

      1. http://blogs.msdn.com/mikehillberg/archive/2007/07/26/a-context-sensitive-help-provider-in-wpf.aspx

 

      2. http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/3e947603-a883-4ada-9b30-55d365b83c33

 

      3. http://www.codeproject.com/Articles/36117/Easy-help-with-WPF.aspx

 

      经过研究,第1篇讲的比较详细,第2篇一般,第3篇应用范围广,包括了keyword。所以使用的话建议参考第3篇,看介绍的话参考第1篇。

 

      但是在刚开始使用第3篇的代码时遇到了一些问题,还以为代码有问题,做了很大改动还是不行,编译有错,最后回过头来才发现了问题。

      文章作者使用这样的xaml:

            xmlns:help="clr-namespace:HelpProvider;assembly=HelpProvider"
            help:Help.Filename="MyHelpfile.chm"


      因为我的类HelpProvider并没有放在一个独立的工程里面,所以出现错误,而且开始还没有找到错误问题,还以为是静态类、或者Helpname没有定义等问题。

 

     下面我把我测试过的代码贴在下面:

<Window x:Class="TestWPFHelp2.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="Window1" Height="300" Width="300" 
    xmlns:h="clr-namespace:ContextSensitiveHelp"

    h:HelpProvider.Filename="Help1.chm" h:HelpProvider.Keyword="button.html">


    <Grid>

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width='auto'/>

            <ColumnDefinition Width='*'/>

        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>

            <RowDefinition Height='auto'/>

            <RowDefinition Height='auto' />

        </Grid.RowDefinitions>

 

        <TextBlock Grid.Column='0' Grid.Row='0' >Name:</TextBlock>

        <TextBlock Grid.Column='0' Grid.Row='1' >Address</TextBlock>

 

        <TextBox Grid.Column='1' Grid.Row='0' Name='NameField' h:HelpProvider.Keyword="general.html"/>

        <TextBox Grid.Column='1' Grid.Row='1' Name='AddressField'  h:HelpProvider.Keyword="textbox.html"/>

 

    </Grid>

</Window>

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using ContextSensitiveHelp;

 

namespace TestWPFHelp2
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
    }
}

 

namespace ContextSensitiveHelp
{
    /// <summary>
    /// This class provides the ability to easily attach Help functionality to Framework elements.
    /// To use it, you need to add a reference to the HelpProvider in your XAML.
    /// The FilenameProperty specifies the name of the help file, and the KeywordProperty specifies the keyword to be used with the search.
    /// </summary>
    /// <remarks>
    /// The FilenameProperty can be at a higher level of the visual tree than the KeywordProperty, so you don't need to set the filename each time.
    /// </remarks>

    static class HelpProvider
    {
        static HelpProvider()
        {
            CommandManager.RegisterClassCommandBinding(typeof(FrameworkElement),
                new CommandBinding(ApplicationCommands.Help,
                    new ExecutedRoutedEventHandler(Executed),
                    new CanExecuteRoutedEventHandler(CanExecute)));
        }

        #region Filename

        /// <summary>
        /// Filename Attached Dependency Property
        /// </summary>
        public static readonly DependencyProperty FilenameProperty =
          DependencyProperty.RegisterAttached("Filename", typeof(string), typeof(HelpProvider));

        /// <summary>
        /// Gets the Filename property.
        /// </summary>
        public static string GetFilename(DependencyObject d)
        {
            return (string)d.GetValue(FilenameProperty);
        }

        /// <summary>
        /// Sets the Filename property.
        /// </summary>
        public static void SetFilename(DependencyObject d, string value)
        {
            d.SetValue(FilenameProperty, value);
        }

        #endregion

        #region Keyword

        /// <summary>
        /// Keyword Attached Dependency Property
        /// </summary>
        public static readonly DependencyProperty KeywordProperty =
          DependencyProperty.RegisterAttached("Keyword", typeof(string), typeof(HelpProvider));

        /// <summary>
        /// Gets the Keyword property.
        /// </summary>
        public static string GetKeyword(DependencyObject d)
        {
            return (string)d.GetValue(KeywordProperty);
        }

        /// <summary>
        /// Sets the Keyword property.
        /// </summary>
        public static void SetKeyword(DependencyObject d, string value)
        {
            d.SetValue(KeywordProperty, value);
        }
        #endregion

        #region Event
        private static void CanExecute(object sender, CanExecuteRoutedEventArgs args)
        {
            FrameworkElement el = sender as FrameworkElement;
            if (el != null)
            {
                string fileName = FindFilename(el);
                if (!string.IsNullOrEmpty(fileName))
                    args.CanExecute = true;
            }
        }

        private static void Executed(object sender, ExecutedRoutedEventArgs args)
        {
            // Call ShowHelp.
            DependencyObject parent = args.OriginalSource as DependencyObject;
            string keyword = GetKeyword(parent);
            if (!string.IsNullOrEmpty(keyword))
            {
                System.Windows.Forms.Help.ShowHelp(null, FindFilename(parent), keyword);
            }
            else
            {
                System.Windows.Forms.Help.ShowHelp(null, FindFilename(parent));
            }
        }

        private static string FindFilename(DependencyObject sender)
        {
            if (sender != null)
            {
                string fileName = GetFilename(sender);
                if (!string.IsNullOrEmpty(fileName))
                    return fileName;
                return FindFilename(VisualTreeHelper.GetParent(sender));
            }
            return null;
        }
        #endregion
    }
}

 

代码和.chm文件上传到了csdn资源,点击下载:Test WPF Help Project .rar

(help1.chm文件在/bin/Debug/Help1.chm)

 

      测试的时候,发现即使某个控件如TextBox没有定义Keyword,它所显示的帮助文档的Keyword是其他控件的,而不是父窗口的,所以我增加了一个函数:

        private static string FindKeyword(DependencyObject sender)
        {
            if (sender != null)
            {
                string keyword = GetKeyword(sender);
                if (!string.IsNullOrEmpty(keyword))
                    return keyword;
                return FindKeyword(VisualTreeHelper.GetParent(sender));
            }
            return null;
        }

 

 并且修改了这个函数:

        private static void Executed(object sender, ExecutedRoutedEventArgs args)
        {
            // Call ShowHelp.
            DependencyObject parent = args.OriginalSource as DependencyObject;
            string keyword = FindKeyword(parent);
            string filename = FindFilename(parent);

            if (!string.IsNullOrEmpty(keyword))
            {
                System.Windows.Forms.Help.ShowHelp(null, filename, keyword);
            }
            else
            {
                System.Windows.Forms.Help.ShowHelp(null, filename);
            }
        }

 

      这样的话工作就比较正常了。

 

      同时,使用了ShowHelpIndex去显示Index:

             System.Windows.Forms.Help.ShowHelpIndex(null, FindFilename(parent));

 

      Help::ShowHelp还有一些重载函数,大家可以根据自己需求进行更改,会有更好的效果。

      具体查看msdn:http://msdn.microsoft.com/en-us/library/system.windows.forms.help.showhelp.aspx

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值