Converting from VB6 or Winforms to Context-Sensitive Help in Silverlight

If you were in VB6 HelpContextID will be familiar for you (http://msdn.microsoft.com/en-us/library/aa267690(v=vs.60).aspx). In those sweet VB6 days all you had to do was:

Private Sub Form_Load ()
   App.HelpFile = "VB.HLP"
   Frame1.HelpContextID = 21004   
   Text1.HelpContextID = 21001
   Form1.HelpContextID = 21005
End Sub

And each time you pressed the F1 button your application will have opened the .hlp file and show you the Help Topic corresponding to that ID. After migration from VB6 to WinForms Help you now have the HelpProvider.SetHelpKeyword http://msdn.microsoft.com/en-us/library/system.windows.forms.helpprovider.sethelpkeyword.aspx And you had to do something like:

internal System.Windows.Forms.HelpProvider HelpProvider1;
...
HelpProvider1.HelpNamespace = "sample.chm";
HelpProvider1.SetHelpKeyword(TextBox1, "1007.html");
HelpProvider1.SetHelpNavigator(TextBox1, HelpNavigator.Topic);
HelpProvider1.SetHelpKeyword(ListBox1, "1006.html");
HelpProvider1.SetHelpNavigator(ListBox1, HelpNavigator.Topic);

And all that seems nice. But, what can you do when you cross over to SilverlightjQuery15205164761650376022_1357918518660? Well, in general there are several systems that allow you to author your help files in html or convert your .hlp or .chm files to html, but how do you link your components to that help system in order to provide context-sensitive help???? Ok. So one of the possible solutions is very very simple. In general, the solution that I will show in this post is this: 1) First implement an attached property for adding a HelpKeyword to Silverlight components 2) Set the helpkeyword in the desired components 3) Provide logic that will open the appropiate help file. Ok. So let's implement a Silverlight Attached property. An attached propery is like adding a new property to your controls. This new attached property will be called Helpkeyword

using System;
using System.Windows.Shapes;
namespace System.Windows.Controls
{
    public class HelpProvider
    {
        public static readonly DependencyProperty HelpKeyword = 
            DependencyProperty.RegisterAttached("HelpKeyword", typeof(string), typeof(HelpProvider), new PropertyMetadata(null));
        public static void SetHelpKeyword(UIElement element, string keyword)
        {
            element.SetValue(HelpKeyword, keyword);
        }

        public static string GetHelpKeyword(UIElement element)
        {
            return (string)element.GetValue(HelpKeyword);
        }
    }
}

Ok. So once we have the attached property we have to use it, and set it on the code: To set it on the code we must add a namespace:

<UserControl x:Class="SilverlightApplication.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ...    
    xmlns:help="clr-namespace:System.Windows.Controls"
    mc:Ignorable="d"
    ....>

And apply the attribute to components

<Button help:HelpProvider.HelpKeyword="helpforbutton1" Content="Button" ...  />
<TextBox help:HelpProvider.HelpKeyword="helpfortext1" Height="47" ... />

So that almost everything, now we just need to trigger the appropiate logic, to do that we will add a KeyUp handler to the top most element, in this example a grid. NOTE: if Silverlight is running on the browser F1 is not an option. I just used F2 here as an example.

<Grid x:Name="LayoutRoot" Background="White" Height="205" KeyUp="LayoutRoot_KeyUp">
<Button help:HelpProvider.HelpKeyword="helpforbutton1" ...  />
<TextBox help:HelpProvider.HelpKeyword="helpfortext1" ... />
</Grid>
 
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Browser;

namespace SilverlightApplication
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void LayoutRoot_KeyUp(object sender, KeyEventArgs e)
        {
            //check for the specific key. For now use F2 as the Help Shortcut
            if (e.Key==Key.F2) { 
                    var uielement = FocusManager.GetFocusedElement() as UIElement;
                    if (uielement!=null)
                    {
                        
                        var keyword = HelpProvider.GetHelpKeyword(uielement);
                        var host = HtmlPage.Document.DocumentUri.Host;
                        var port = HtmlPage.Document.DocumentUri.Port;
                        var url = string.Format("http://{0}:{1}/help/{2}.html", host,port,keyword);
                        HtmlPage.Window.Navigate(new Uri(url),"_blank");
                    }
            } // else ignore the keystroke
        }
    }
}
This property can be used on the IDE:

On code
var uielement = FocusManager.GetFocusedElement() as UIElement; 
if (uielement!=null) { 
var keyword = HelpProvider.GetHelpKeyword(uielement); 
}
This is an image of the application running.

And you can download the code from: CODE

If you have any questions or would like more info on Silverlight migration check www.silverlightmigration.com

.HLP files in Windows Vista

13. May 2010 04:07 by Mrojas in General  //  Tags: , , , , ,   //   Comments (0)

Microsoft has decided that .hlp files are not the best option for your help files.

And you will probably receive an error message like: http://support.microsoft.com/kb/917607

If you still want to run your .hlp help files you still can look for a WinHelp viewer for Vista from Microsoft.

But as someone that has been in the application migration/upgrade bussiness for several year I think automatic migration is a very good option.

 

For example take a look at the following links:

 

 

http://www.herdsoft.com/linux/themen/hlp_to_chm.html 

Some guidance and scripts to help in migrating your files
http://www.helpscribble.com/vista.html Tools to automatically upgrade your .hlp files and projects

Good luck! And If you had any other suggestions just leave a comment.