The obvious choice for implementing a link to a Web site in WPF is the Hyperlink class. Note, however, that the Hyperlink class is a FrameworkContentElement, which means it doesn’t know how to render itself, but must be hosted by a TextBlock or a FlowDocument viewer like FlowDocumentScrollViewer or RichTextBox. So the easiest way to display a hyperlink is to wrap it in a TextBlock.
If your application is hosted in Internet Explorer (XBAP or loose XAML), the browser will be navigated accordingly. If the Hyperlink is in the Page of a NavigationWindow or Frame, that window or frame will be navigated.
The Hyperlink doesn’t work at all from a standalone Window, however. Lauren Lavoie discusses the workaround – your application needs to intercept the navigation and use Process.Start with the URL to launch the default browser. The best way to do that is to handle the Hyperlink.RequestNavigate routed event on the Hyperlink or one of its ancestors. (You could also just handle the Hyperlink.Click event, but Lauren’s solution seems better.) And the easiest way to do that is with an attached dependency property:
And how is that dependency property implemented? We have some really cool utility code for registering dependency properties in a type-safe manner, but I’ll use traditional methods for now:
But wait, what is ElementUtility? I guess I couldn’t avoid our utility code entirely - ElementUtility.AddHandler calls UIElement.AddHandler, ContentElement.AddHandler, or UIElement3D.AddHandler, depending on the type of the element. Similarly with ElementUtility.RemoveHandler. This dependency property should be supported on the TextBlock (a UIElement) or the Hyperlink (a ContentElement), so we need to support both types of elements. The implementation of AddHandler and RemoveHandler is left as an exercise for the reader.
I also want to talk more about Process.Start, but that will have to wait until my next post.
Posted by Ed Ball on January 17, 2008