Exercise 1 – Getting Started

The goal of this exercise is to familiarize the student with the existing starter application and add new functionality into the application.

  1. Start Visual Studio 2010
  2. On the File menu click OpenProject/Solution…
    1. Alternatively, from Visual Studio Start Page click Open Project…
      1. At the Open Project dialog navigate to the Lab installation folder
      2. Navigate to RichTextBox\Source\Ex01\Begin folder
      3. Click the RichTextBox.sln file and then click the Open button
  3. The project will not currently build since we'll be adding specific functionality. You can ignore any warnings that may appear at this point.
  4. Set the RichTextBox.Web project as the startup project by right clicking the project in the Solution Explorer and selecting “Set as Startup Project”

Task 1 – Building a Text Editor UI

In order to use the rich text formatting offered by the RichTextBox control we need a set of buttons that will allow end users to perform text formatting functions. We'll start by building a ribbon user interface much like you've seen in Word 2007 or higher.

  1. If you haven't opened the Starter project open it now (see previous section for detailed instructions)
  2. Double-click the XAML tab below the designer window to open the XAML code editor in full screen mode
  3. Open MainPage.xaml and locate the <!-- RichTextBoxControl --> comment. Replace the existing RichTextBox element with the following:

    XAML

    <RichTextBox x:Name="rtb" SelectionChanged="rtb_SelectionChanged" VerticalScrollBarVisibility="Auto" KeyUp="rtb_KeyUp" BorderBrush="{x:Null}" Margin="8,10,10,8" FontSize="20" TextWrapping="Wrap" MouseRightButtonDown="rtb_MouseRightButtonDown" MouseRightButtonUp="rtb_MouseRightButtonUp" MouseMove="rtb_MouseMove" DragEnter="rtb_DragEnter" DragLeave="rtb_DragLeave"/>
  4. In MainPage.xaml file. Scroll to the bottom and locate <!-- TODO Toolbar goes here --> which is located toward the bottom of the file. We will add a Grid after this comment to create containers and placeholders for buttons. Add the following code:

    XAML

    <Grid Margin="3,3,3,1"> <Grid.RowDefinitions> <RowDefinition Height="27"/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="102"/> <ColumnDefinition Width="176"/> <ColumnDefinition Width="184"/> <ColumnDefinition Width="73"/> <ColumnDefinition Width="106"/> <ColumnDefinition Width="80"/> <ColumnDefinition Width="80"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Rectangle Margin="0,-26,0,2" Grid.RowSpan="1" Fill="{StaticResource MenuDividerBrush}" Grid.Row="1" RadiusX="2" RadiusY="2" Stroke="#FFA5BED4"/> <Rectangle Margin="2,-26,0,2" Fill="{StaticResource MenuDividerBrush}" Grid.Column="1" Grid.Row="1" RadiusX="2" RadiusY="2" Stroke="#FFA5BED4"/> <Rectangle Margin="2,-26,0,2" Fill="{StaticResource MenuDividerBrush}" Grid.Column="2" Grid.Row="1" RadiusX="2" RadiusY="2" Stroke="#FFA5BED4"/> <Rectangle Margin="2,-26,0,2" Fill="{StaticResource MenuDividerBrush}" Grid.Column="3" Grid.Row="1" RadiusX="2" RadiusY="2" Stroke="#FFA5BED4"/> <Rectangle Margin="2,-26,0,2" Fill="{StaticResource MenuDividerBrush}" Grid.Column="4" Grid.Row="1" RadiusX="2" RadiusY="2" Stroke="#FFA5BED4"/> <Rectangle Margin="2,-26,0,2" Fill="{StaticResource MenuDividerBrush}" Grid.Column="5" Grid.Row="1" RadiusX="2" RadiusY="2" Stroke="#FFA5BED4"/> <Rectangle Margin="2,-26,0,2" Fill="{StaticResource MenuDividerBrush}" Grid.Column="6" Grid.Row="1" RadiusX="2" RadiusY="2" Stroke="#FFA5BED4"/> <Rectangle Margin="2,-26,0,2" Fill="{StaticResource MenuDividerBrush}" Grid.Column="7" Grid.Row="1" RadiusX="2" RadiusY="2" Stroke="#FFA5BED4"/> <!-- TODO - Font Buttons--> <!-- TODO - Clipboard Buttons--> <!-- TODO - Insert Buttons--> <!-- TODO - Print Button--> <!-- TODO - Display, Highlight, Xaml Buttons--> <TextBlock Style="{StaticResource MenuLabel}" Text="Clipboard" Grid.Row="1"/> <TextBlock Style="{StaticResource MenuLabel}" Text="Font" Grid.Column="1" Grid.Row="1"/> <TextBlock Style="{StaticResource MenuLabel}" Text="Insert" Grid.Column="2" Grid.Row="1"/> <TextBlock Style="{StaticResource MenuLabel}" Text="Print" Grid.Column="3" Grid.Row="1"/> <TextBlock Style="{StaticResource MenuLabel}" Text="Display" Grid.Column="4" Grid.Row="1"/> <TextBlock Style="{StaticResource MenuLabel}" Text="Highlight" Grid.Column="5" Grid.Row="1"/> <TextBlock Style="{StaticResource MenuLabel}" Text="XAML" Grid.Column="6" Grid.Row="1"/> </Grid>
  5. Press F5 to Run the application. Notice the Grid has columns to act as placeholders for the buttons and functionality that will be added.

    Figure 1

    Browser showing grid with placeholder for buttons

  6. Now we'll load a file to pre-populate the RichTextBox with some formatted Xaml text. Open MainPage.xaml.cs file and near the top of the file locate // TODO Add sample Xaml file here in the MainPage_Loaded event. Add the following code to load from a file named SampleNew.sav and assign to the RichTextBox control's Xaml property:

    C#

    StreamResourceInfo sr = App.GetResourceStream(new Uri("/RichNotepad;component/sampleNew.sav", UriKind.Relative)); StreamReader sread = new StreamReader(sr.Stream); string xaml = sread.ReadToEnd(); rtb.Xaml = xaml; sread.Close();
  7. Press F5 to run the project and notice that we now have formatted text loaded into the RichTextBox control.

    Figure 2

    Browser showing dynamic text loaded

  8. Close the browser and return back to Visual Studio
  9. Go to MainPage.xaml and scroll to the bottom. Locate the <!-- TODO - Font Buttons--> comment. Insert the following code to add the font formatting buttons:

    XAML

    <!--Fonts Face Combo--> <ComboBox x:Name="cmbFonts" FontFamily="{Binding SelectedItem.FontFamily, RelativeSource={RelativeSource Self}}" FontSize="{Binding SelectedItem.FontSize, RelativeSource={RelativeSource Self}}" Grid.Column="1" Margin="6,0,55,0" Height="22" VerticalAlignment="Bottom" > <ComboBoxItem Content="Arial" Tag="Arial" FontFamily="Arial" FontSize="12"/> <ComboBoxItem Content="Arial Black" Tag="Arial Black" FontFamily="Arial Black" FontSize="12"/> <ComboBoxItem Content="Calibri" Tag="Calibri" FontFamily="Calibri" IsSelected="True" FontSize="14"/> <ComboBoxItem Content="Comic Sans MS" Tag="Comic Sans MS" FontFamily="Comic Sans MS" FontSize="12"/> <ComboBoxItem Content="Courier New" Tag="Courier New" FontFamily="Courier New" FontSize="12"/> <ComboBoxItem Content="Georgia" Tag="Georgia" FontFamily="Georgia" FontSize="12"/> <ComboBoxItem Content="Lucida Sans Unicode" Tag="Lucida Sans Unicode" FontFamily="Lucida Sans Unicode" FontSize="12"/> <ComboBoxItem Content="Portable User Interface" Tag="{x:Null}" FontFamily="Portable User Interface" FontSize="12"/> <ComboBoxItem Content="Times New Roman" Tag="Times New Roman" FontFamily="Times New Roman" FontSize="12"/> <ComboBoxItem Content="Trebuchet MS" Tag="Trebuchet MS" FontFamily="Trebuchet MS" FontSize="12"/> <ComboBoxItem Content="Verdana" Tag="Verdana" FontFamily="Verdana" FontSize="12"/> <ComboBoxItem Content="Webdings" Tag="Webdings" FontSize="12"/> </ComboBox> <ComboBox x:Name="cmbFontSizes" Width="44" FontSize="14" HorizontalAlignment="Right" Margin="0,0,6,0" Grid.Column="1" Height="22" VerticalAlignment="Bottom"> <ComboBoxItem Content="8" Tag="8"/> <ComboBoxItem Content="9" Tag="9"/> <ComboBoxItem Content="10" Tag="10"/> <ComboBoxItem Content="11" Tag="11"/> <ComboBoxItem Content="12" Tag="12"/> <ComboBoxItem Content="14" Tag="14"/> <ComboBoxItem Content="16" Tag="16" IsSelected="True"/> <ComboBoxItem Content="18" Tag="18"/> <ComboBoxItem Content="20" Tag="20"/> <ComboBoxItem Content="22" Tag="22"/> <ComboBoxItem Content="24" Tag="24"/> <ComboBoxItem Content="26" Tag="26"/> <ComboBoxItem Content="28" Tag="28"/> <ComboBoxItem Content="36" Tag="36"/> <ComboBoxItem Content="48" Tag="48"/> <ComboBoxItem Content="72" Tag="72"/> </ComboBox> <StackPanel Grid.Column="1" Height="22" Margin="6,5,0,0" Orientation="Horizontal" Grid.Row="1" VerticalAlignment="Top"> <!--Font Formatting Buttons--> <Button x:Name="btnBold" Margin="0,0,1,0"> <ToolTipService.ToolTip> <ToolTip FontSize="16" Content="{Binding tooltip_Bold, Source={StaticResource localizedStrings}}"/> </ToolTipService.ToolTip> <Image Source="Images/Bold.png" d:IsLocked="True"/> </Button> <Button x:Name="btnItalic" Margin="0,0,1,0"> <ToolTipService.ToolTip> <ToolTip FontSize="16" Content="{Binding tooltip_Italic, Source={StaticResource localizedStrings}}"/> </ToolTipService.ToolTip> <Image Source="Images/Italic.png"/> </Button> <Button x:Name="btnUnderline" Margin="0,0,13,0"> <ToolTipService.ToolTip> <ToolTip FontSize="16" Content="Underline"/> </ToolTipService.ToolTip> <Image Source="Images/Underline.png"/> </Button> <ComboBox x:Name="cmbFontColors" SelectedIndex="0" Margin="39,0,0,0" HorizontalAlignment="Right"> <ComboBoxItem Tag="FFFF0000"> <Rectangle Width="22" Height="14" Fill="Red" Margin="2,0,0,0" /> </ComboBoxItem> <ComboBoxItem Tag="FF008000"> <Rectangle Width="22" Height="14" Fill="Green" Margin="2,0,0,0" /> </ComboBoxItem> <ComboBoxItem Tag="FF0000FF"> <Rectangle Width="22" Height="14" Fill="Blue" Margin="2,0,0,0" /> </ComboBoxItem> <ComboBoxItem Tag="FFFFFF00"> <Rectangle Width="22" Height="14" Fill="Yellow" Margin="2,0,0,0" /> </ComboBoxItem> <ComboBoxItem Tag="FF000000" IsSelected="True"> <Rectangle Width="22" Height="14" Fill="Black" Margin="2,0,0,0" /> </ComboBoxItem> </ComboBox> </StackPanel>
  10. In the code you just inserted into MainPage.xaml, find the button named btnBold. Add a new Click event handler (use the default name).

    Figure 3

    Event Handler Generation from XAML Editor

  11. Right-click btnBold_Click and select Navigate to Event Handler from the context menu

    Figure 4

    Navigate to Event Handler from XAML Editor

  12. The last action will take you into the source code editor and to the event handler:

    C#

    private void btnBold_Click(object sender, RoutedEventArgs e) { }
  13. Since we want to set the selected text to bold, we'll add the following if statement to check whether the user selected some text prior to pressing the button. Add the following code in the btnBold_Click method:

    C#

    if (rtb != null && rtb.Selection.Text.Length > 0) { } ReturnFocus();
  14. Once we have a selection, all that is left to do is to change the font's weight from normal to bold or vice versa according to whether the button is toggled or not. We'll need to check the current font style and apply the opposite (in case the selection is mixed we'll remove the bold style). Add the following code inside the if statement to perform the style modification:

    C#

    if (rtb.Selection.GetPropertyValue(Run.FontWeightProperty) is FontWeight && ((FontWeight)rtb.Selection.GetPropertyValue(Run.FontWeightProperty)) == FontWeights.Normal) rtb.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Bold); else rtb.Selection.ApplyPropertyValue(Run.FontWeightProperty, FontWeights.Normal);
  15. Add a Click event handler for btnItalic (following the same process you followed for btnBold above).
  16. Place the following code in the btnItalic_Click event handler and take a moment to look through the code.

    C#

    if (rtb != null && rtb.Selection.Text.Length > 0) { if (rtb.Selection.GetPropertyValue(Run.FontStyleProperty) is FontStyle && ((FontStyle)rtb.Selection.GetPropertyValue(Run.FontStyleProperty)) == FontStyles.Normal) rtb.Selection.ApplyPropertyValue(Run.FontStyleProperty, FontStyles.Italic); else rtb.Selection.ApplyPropertyValue(Run.FontStyleProperty, FontStyles.Normal); } ReturnFocus();
  17. Add a Click event handler for btnUnderline
  18. Place the following code in the btnUnderline_Click event handler:

    C#

    if (rtb != null && rtb.Selection.Text.Length > 0) { if (rtb.Selection.GetPropertyValue(Run.TextDecorationsProperty) == null) rtb.Selection.ApplyPropertyValue(Run.TextDecorationsProperty, TextDecorations.Underline); else rtb.Selection.ApplyPropertyValue(Run.TextDecorationsProperty, null); } ReturnFocus();
  19. Next, we'll handle font family changes. When the user changes the font in the fonts ComboBox control, we'll change the font family of the current selected text. Find the ComboBox named cmbFonts and add an event handler for the SelectionChanged event.
  20. Add the following code into the cmbFonts_SelectionChanged event handler:

    C#

    if (rtb != null && rtb.Selection.Text.Length > 0) { rtb.Selection.ApplyPropertyValue(Run.FontFamilyProperty, new FontFamily((cmbFonts.SelectedItem as ComboBoxItem).Tag.ToString())); } ReturnFocus();
  21. Let's do the same to modify the text size. Find the ComboBox named cmbFontSizes, add a default event handler for the SelectionChanged event and add the following code to the event handler:

    C#

    if (rtb != null && rtb.Selection.Text.Length > 0) { rtb.Selection.ApplyPropertyValue(Run.FontSizeProperty, double.Parse((cmbFontSizes.SelectedItem as ComboBoxItem).Tag.ToString())); } ReturnFocus();
  22. Find the cmbFontColors ComboBox and examine how each color is represented as a string of HEX values representing the color and stored in the "Tag" property of the ComboBoxItem element. In order to break that string into ARGB (Alpha/Red/Green/Blue) format, we'll need to do some parsing.
  23. Create a default event handler for the SelectionChanged event of cmbFontColors and add the following code to the event handler:

    C#

    if (rtb != null && rtb.Selection.Text.Length > 0) { string color = (cmbFontColors.SelectedItem as ComboBoxItem).Tag.ToString(); SolidColorBrush brush = new SolidColorBrush(Color.FromArgb( byte.Parse(color.Substring(0, 2), System.Globalization.NumberStyles.HexNumber), byte.Parse(color.Substring(2, 2), System.Globalization.NumberStyles.HexNumber), byte.Parse(color.Substring(4, 2), System.Globalization.NumberStyles.HexNumber), byte.Parse(color.Substring(6, 2), System.Globalization.NumberStyles.HexNumber))); rtb.Selection.ApplyPropertyValue(Run.ForegroundProperty, brush); }
  24. Run the application by pressing F5.
  25. Enter some text (or use the pre-loaded text), select it and press the bold button. The text has become bold. Press the bold button again and the text will return to normal. If you select mixed text (some characters bold and some normal) and press the bold button, the text will return to normal. Try experimenting with the other text formatting features including fonts and font colors.

Task 2 – Embedded Elements

In this exercise we will allow users to add hyperlinks, images, datagrids and calendars into the RichTextBox control.

  1. In MainPage.xaml locate the comment <!-- TODO - Insert Buttons--> and insert the following code to create the buttons for inserting an image, hyperlink, DataGrid and calendar.

    XAML

    <Button x:Name="btnImage" HorizontalAlignment="Left" Grid.Column="2" Margin="13,-22,0,24" Grid.RowSpan="1" Grid.Row="1"> <ToolTipService.ToolTip> <ToolTip FontSize="16" Content="{Binding tooltip_Image, Source={StaticResource localizedStrings}}"/> </ToolTipService.ToolTip> <Image Source="Images/Image.png" Height="32" Width="30"/> </Button> <Button x:Name="btnHyperlink" Grid.Column="2" Margin="55,-22,0,24" Grid.RowSpan="1" Grid.Row="1" HorizontalAlignment="Left"> <ToolTipService.ToolTip> <ToolTip FontSize="16" Content="{Binding tooltip_Hyperlink, Source={StaticResource localizedStrings}}"/> </ToolTipService.ToolTip> <Image Source="Images/Hyperlink_big.png" Width="30" Height="32"/> </Button> <Button x:Name="btnDatagrid" Grid.Column="2" Grid.RowSpan="1" Margin="97,-22,0,24" HorizontalAlignment="Left" Grid.Row="1"> <ToolTipService.ToolTip> <ToolTip FontSize="16" Content="Insert Datagrid"/> </ToolTipService.ToolTip> <Image Source="Images/datagrid.png" Width="29" Height="32"/> </Button> <Button x:Name="btnCalendar" Grid.Column="2" Grid.RowSpan="1" Margin="138,-22,0,24" HorizontalAlignment="Left" Grid.Row="1"> <ToolTipService.ToolTip> <ToolTip FontSize="16" Content="Insert Calendar"/> </ToolTipService.ToolTip> <Image Source="Images/calendar.png" Width="29" Height="32"/> </Button>
  2. Locate the btnImage button. Add a default event handler for the Click event and navigate to the event handler.
  3. In order to add an image to the RichTextBox we need to create an InlineUIContainer object that will contain the image presented by the RichTextBox. Add the following code to the btnImage_Click event handler function:

    C#

    InlineUIContainer container = new InlineUIContainer();container.Child = getImage(); rtb.Selection.Insert(container); ReturnFocus();
  4. Now that we have a container, we can load a sample image into it (you can find the image in the ClientBin folder of the Web Project). Add the following code into MainPage.xaml.cs to create a method capable of loading an image and placing it in the container:

    C#

    private Image getImage() { return CreateImageFromUri(new Uri("desert.jpg", UriKind.RelativeOrAbsolute), 200, 150); }
  5. Compile and run the application by pressing F5. Press the insert image button and an image will appear in the RichTextBox control.
  6. To add a hyperlink to the RichTextBox control we'll use a child window to allow the user to input a hyperlink and a description for it. The ChildWindow class was introduced in Silverlight 3 and is used to implement popup windows you can interact with. Find the file InsertURL.xaml and the file InsertURL.xaml.cs and take a moment to look through their code. Examine the validation code in the InsertURL.xaml.cs class.
  7. Back in MainPage.xaml, find the btnHyperlink button and add an event handler for the Click event. To show the InsertURL child window add the following code to the event handler:

    C#

    InsertURL cw = new InsertURL(rtb.Selection.Text); cw.HasCloseButton = false; cw.Show();
  8. The previous code will show the child window, but after confirming the URL we need to fetch it from the child window and place it in the RichTextBox. Add the following code to handle the Close event of the child window (place the code before calling the Show method)

    C#

    cw.Closed += (s, args) => { if (cw.DialogResult.Value) { } };
  9. Next, we'll create a Hyperlink object and place it inside the RichTextBox. Place the following code inside the if statement from the last step.

    C#

    Hyperlink hyperlink = new Hyperlink(); hyperlink.TargetName = "_blank"; hyperlink.NavigateUri = new Uri(cw.txtURL.Text); if (cw.txtURLDesc.Text.Length > 0) hyperlink.Inlines.Add(cw.txtURLDesc.Text); else hyperlink.Inlines.Add(cw.txtURL.Text); rtb.Selection.Insert(hyperlink);
  10. Locate the btnDatagrid button in MainPage.xaml, add a Click event handler and add the following code into the event handler:

    C#

    InlineUIContainer container = new InlineUIContainer(); container.Child = getDataGrid(); rtb.Selection.Insert(container); ReturnFocus();
  11. Add the following method into the MainPage.xaml.cs file to create a new DataGrid instance:

    C#

    private DataGrid getDataGrid() { DataGrid dg = new DataGrid(); dg.AutoGenerateColumns = true; dg.Width = 500; dg.Height = 150; dg.ItemsSource = Customer.GetSampleCustomerList(); dg.Style = (Style)this.Resources["DataGridStyle1"]; return dg; }
  12. Locate the btnCalendar button in MainPage.xaml, add a Click event handler and add the following code into the event handler:

    C#

    InlineUIContainer container = new InlineUIContainer(); container.Child = getCalendar(); rtb.Selection.Insert(container); ReturnFocus();
  13. Add the following method into the MainPage.xaml.cs file to create a new Calendar instance:

    C#

    private Calendar getCalendar() { Calendar cal = new Calendar(); cal.Width = 179; cal.Height = 169; cal.FontFamily = new FontFamily("Portable User Interface"); cal.Style = (Style)this.Resources["CalendarStyle1"]; return cal; }
  14. At this point we've seen that InlineUIContainer can act as the container for different types of objects. Compile and run the application by pressing F5. Press the image, hyperlink, datagrid and calendar buttons to test the functionality.

Task 3 – Persisting content

Now that our editor supports inputting text and styling it let's see how we can save documents.

  1. Open Mainpage.xaml, locate the comment remark <!-- TODO - Open, Save, New Buttons-->, and add the following stack panel control which will house our New, Open, and Save buttons.

    XAML

    <StackPanel Grid.RowSpan="1" Grid.Column="4" Margin="8" VerticalAlignment="Top" HorizontalAlignment="Right" Orientation="Horizontal" Grid.Row="0"> <!--New Button--> <Button x:Name="btnNew" HorizontalAlignment="Left" Height="22" Margin="0,0,0,0" VerticalAlignment="Top" Width="22"> <ToolTipService.ToolTip> <ToolTip FontSize="16" Content="{Binding tooltip_New, Source={StaticResource localizedStrings}}"/> </ToolTipService.ToolTip> <Image Source="Images/New.png"/> </Button> <!--Open Existing Button --> <Button x:Name="btnOpen" HorizontalAlignment="Left" Height="22" Margin="0,0,0,4" VerticalAlignment="Top" Width="22"> <ToolTipService.ToolTip> <ToolTip FontSize="16" Content="{Binding tooltip_Open, Source={StaticResource localizedStrings}}"/> </ToolTipService.ToolTip> <Image Source="Images/Open.png"/> </Button> <!--Save Existing Button --> <Button x:Name="btnSave" HorizontalAlignment="Left" Height="22" VerticalAlignment="Top" Width="22"> <ToolTipService.ToolTip> <ToolTip FontSize="16" Content="{Binding tooltip_Save, Source={StaticResource localizedStrings}}"/> </ToolTipService.ToolTip> <Image Source="Images/Save.png"/> </Button> </StackPanel>
  2. In MainPage.xaml locate the btnNew button and add a default event handler for the Click event. Add the following code to the event handler:

    C#

    bool clear = true; if (IsDirty) { if (MessageBox.Show("All changes will be lost. Continue?", "Continue", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel) { clear = false; } } if (clear) { rtb.Blocks.Clear(); IsDirty = false; }
  3. Go back to the MainPage.xaml, locate the btnSave button and add a default event handler for the Click event. Add the following into the event handler:

    C#

    string xaml = rtb.Xaml; SaveFileDialog sfd = new SaveFileDialog(); sfd.DefaultExt = ".sav"; sfd.Filter = "Saved Files|*.sav|All Files|*.*"; if (sfd.ShowDialog().Value) { }
  4. All that is left to do is take the content, write it into the selected file and reset an IsDirty variable. Add the following code inside the if statement:

    C#

    using (FileStream fs = (FileStream)sfd.OpenFile()) { System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); byte[] buffer = enc.GetBytes(xaml); fs.Write(buffer, 0, buffer.Length); fs.Close(); IsDirty = false; }
  5. Before we can test this code, we need to be able to open the saved file. Go to MainPage.xaml and locate the btnOpen button. Add a default event handler for the Click event and navigate to it.
  6. Next we'll use the OpenFileDialog class to ask the user to select which document to open. Place the following code after calling the btnOpen_Click method:

    C#

    OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = false; ofd.Filter = "Saved Files|*.sav|All Files|*.*"; if (ofd.ShowDialog().Value) { }
  7. Add the following code into the if statement:

    C#

    FileInfo fi = ofd.File; using (StreamReader reader = fi.OpenText()) { rtb.Xaml = reader.ReadToEnd(); }
  8. Compile and run the application by pressing F5. Enter some text and test the save and load features.