Click here to Skip to main content
13,894,145 members
Click here to Skip to main content
Add your own
alternative version


33 bookmarked
Posted 1 May 2009
Licenced CPOL

Easy Help with WPF

, 1 May 2009
Rate this:
Please Sign up or sign in to vote.
Adding simple HelpProvider functionality to your WPF applications couldn't be easier.

If, like me, you like your applications to provide Context sensitive help, you’ve probably had a play around with the ApplicationCommands.Help command. In order to simplify hooking your help into your application, I’ve written the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
using form = System.Windows.Forms;
using System.Windows.Media;

namespace HelpProvider
  /// <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
  /// is used to specify the name of the helpfile, 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>
  public static class Help
    /// <summary>
    /// Initialize a new instance of <see cref="Help"/>.
    /// </summary>
    static Help()
      // Rather than having to manually associate the Help command, let's take care
      // of this here.
        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(Help));

    /// <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);

    #region Keyword

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

    /// <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);

    #region Helpers
    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))
        form.Help.ShowHelp(null, FindFilename(parent), keyword);
        form.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;


Using it couldn’t be simpler, set up the Filename in your XAML and add any keywords you need to search on against your FrameworkElement items. The advantage of this approach is that you can bind different parts of your UI to different helpfiles if you want.



  xmlns="<a href=""></a>"
  xmlns:x="<a href=""></a>"
  Title="Window1" Height="300" Width="300"

I hope this helps you as much as it helps me.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Pete O'Hanlon
United Kingdom United Kingdom
A developer for over 30 years, I've been lucky enough to write articles and applications for Code Project as well as the Intel Ultimate Coder - Going Perceptual challenge. I live in the North East of England with 2 wonderful daughters and a wonderful wife.

I am not the Stig, but I do wish I had Lotus Tuned Suspension.

You may also be interested in...


Comments and Discussions

GeneralCompile error Pin
LOUIS Christian20-May-10 2:36
memberLOUIS Christian20-May-10 2:36 
QuestionCan you have way to achieve SetHelpString()? Pin
wmjcomcn21-Jul-09 16:19
memberwmjcomcn21-Jul-09 16:19 
GeneralGood article. Pin
wmjcomcn12-Jul-09 20:28
memberwmjcomcn12-Jul-09 20:28 
GeneralRe: Good article. Pin
Pete O'Hanlon12-Jul-09 21:54
protectorPete O'Hanlon12-Jul-09 21:54 
GeneralFilename can't be found. Pin
wmjcomcn9-Jul-09 23:54
memberwmjcomcn9-Jul-09 23:54 
QuestionDo you have source code? Pin
wmjcomcn9-Jul-09 23:39
memberwmjcomcn9-Jul-09 23:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web02 | 2.8.190306.1 | Last Updated 1 May 2009
Article Copyright 2009 by Pete O'Hanlon
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid