Loading rich text file links in a browser from a WPF Navigation Application
Previously, I discussed loading a rich text file in a regular WPF Application in this post:
Loading a RichTextBox from an RTF file using binding or a RichTextFile control
The following use cases must be met:
- Load and display a rich text file in read only mode
- The links must open inside a browser and not in the application
We created a RichTextFile control that inherits RichTextBox and configured it to support binding. Now we are going to use this same object in a WPF Navigation Application.
A WPF Navigation Application is going to react differently. Links are going work by default, so the Hyperlink.Click event doesn’t have to be used. However, there is a problem, the links open in the actual application’s window and not in a browser. Lets fix this.
Part 2 – Using the RichTextFile class in a WPF Navigation Application
Use Case 1 – Loading a rich text file
Create a new WPF Application in Visual Studio.
Add a Frame element and set the source to RTF.xaml, which we will create next.
<Window x:Class="RichTextFileTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <Frame Source="RTF.xaml" /> </Grid> </Window>
There is no code behind for this, yet.
Create a new WPF Page called RTF.xaml.
Add the above RichTextFile object to the project.
Add an xmlns reference to our new object. Then add our new object. Notice in our new object that we set IsReadOnly=”True” but we also set IsDocumentEnabled=”True”. This allows for clicking a link even though the document is read only.
<Page x:Class="RichTextFileTest.RTF" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Title="RTF" xmlns:controls="clr-namespace:System.Windows.Controls"> <Grid> <controls:RichTextFile File="{Binding File}" IsReadOnly="True" IsDocumentEnabled="True"/> </Grid> </Page>
Code Behind
using System; using System.Diagnostics; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; namespace RichTextFileTest { /// <summary> /// Interaction logic for RTF.xaml /// </summary> public partial class RTF : Page { public RTF() { InitializeComponent(); Example example = new Example() { File = "File.rtf" }; DataContext = example; } } public class Example { public String File { get; set; } } }
Now the first use case is complete, the rich text file is loading into the RichTextFile control and is visible in the application. However, the second use case is incomplete, but not because the links aren’t loading, but because they are not loading in a browser. Instead they are loading inside the Frame element.
Use Case 2 – Getting the links to open in a browser
Getting the links to open in a browser is not straight forward and it took me quite some time to find an easy solution. Somehow, the link must be open in a browser and then the Navigation event must be canceled.
The easiest way to do this is to implement the Nagivating function on the Frame element in our MainWindow.
<Window x:Class="RichTextFileTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <Frame Source="RTF.xaml" Navigating="Frame_Navigating"/> </Grid> </Window>
Now implement the code behind for the Frame_Navigating method.
using System.Diagnostics; using System.Windows; using System.Windows.Controls; namespace RichTextFileTest { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Frame_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e) { Frame frame = sender as Frame; if (frame != null && frame.Source != null) { // See if we are hitting a link using HTTP or HTTPS if (frame.Source.ToString().StartsWith("http://", System.StringComparison.CurrentCultureIgnoreCase) || frame.Source.ToString().StartsWith("https://", System.StringComparison.CurrentCultureIgnoreCase)) { // Open the URL in a browser Process.Start(frame.Source.ToString()); // Cancel the Navigation event e.Cancel = true; } } } } }
The links should now be opening in your browser and not in your application.
Here is the sample project that demonstrates this.
RichTextFileNavigation.zip