RichTextBox for WPF | ComponentOne
In This Topic
    Template Customization
    In This Topic

    A template is used in software applications to specify how data, documents, or UI elements are presented visually, either on screen or when printed. They provide an organized way to define and instantiate common patterns or layouts that can be used throughout an application, such as page numbers, document title, author name, dates, etc.

    You can also create a template( or data template) for the C1RichTextBox control to provide a consistent layout while displaying its content. Moreover, the template also helps you control how the content appears on the printed page, including margins, headers, footers, and other printing-specific elements. For example, you can display the header and footer on each page of a multi-page document while displaying it within the C1RichTextBox control.

    Header/Footer

    Following section explains how you can create and customize a template using .NET and .NET Framework versions to display headers and footers on a multi-page RTF document within the C1RichTextBox control.

    1. In the XAML view, create a simple data template with the name printtemplate containing some predefined styles for displaying data. The template uses the C1LayoutTransformer class to apply styles to different elements of data, as shown in the given code snippet.
    2. Add two TextBlock elements in the C1LayoutTransformer class to display header and footer on a document. Adding these <TextBlock> elements for displaying the header and footer allows you to customize the existing data template.
    3. Set the header and footer of the document by using the Text property of the first and second TextBlock elements. For example, the Text property of the first TextBlock element is set to show a simple text message, whereas the Text property of the second TextBlock element is set to show page numbers.
    4. Bind the Text property of the second TextBlock element with the Index property of the data context. Since, the Index property starts index from 0, therefore, you need to create a converter class such as PageNumberConverter to start the index from 1 for properly displaying page numbers in the footer of document. 
      XAML
      Copy Code
      <Window.Resources>
          
          <local:PageNumberConverter x:Key="PageNumberConverter"></local:PageNumberConverter>        
          <DataTemplate x:Key="printtemplate">
              <Grid Margin="4">
                  <Grid.Resources>
                      <c1:ZoomToScaleTransformConverter x:Key="zoomConverter" />
                  </Grid.Resources>
                  <Border BorderThickness="1" BorderBrush="#FF646464" Grid.Row="1" Grid.Column="1" Background="{Binding ViewManager.PresenterInfo.Background}">
                      <Border.Effect>
                          <DropShadowEffect Opacity="0.3" />
                      </Border.Effect>
                  </Border>
                  <c1:C1LayoutTransformer LayoutTransform="{Binding ViewManager.PresenterInfo.Zoom, Converter={StaticResource zoomConverter}}">
                      <Grid Height="{Binding ViewManager.PresenterInfo.Height}" Width="{Binding ViewManager.PresenterInfo.Width}">
                          <c1:C1RichTextPresenter Source="{Binding}" Grid.Row="1" Grid.Column="1" Margin="{Binding ViewManager.PresenterInfo.Padding}"/>
                          <TextBlock Text="{Binding Index,StringFormat='Mark Twain'}" HorizontalAlignment="Right"  VerticalAlignment="Top" 
                                    FontWeight="UltraBold"  FontSize="16" Margin="50" Foreground="Red" />
                         <TextBlock Text="{Binding Index,Converter={StaticResource PageNumberConverter}}" HorizontalAlignment="Right"  
                                    VerticalAlignment="Bottom" FontStyle="Italic" FontSize="14" Margin="50" Foreground="Green" />
                      </Grid>
                  </c1:C1LayoutTransformer>
              </Grid>
          </DataTemplate>
      </Window.Resources>
      
           
    5. Bind the template with the RTF document with the C1RichTextbox control using its PrintTemplate property, as shown in the following code snippet:
      XAML
      Copy Code
      <Grid>
          <c1:C1RichTextBox PrintTemplate="{StaticResource printtemplate}"  x:Name="rtb" Grid.Row="1" Grid.Column="1" Margin="{Binding ViewManager.PresenterInfo.Padding}"/>
      </Grid>
      
           
    6. Load the RTF document into the C1RichTextbox control using the Application class that provides the GetResourceStream method to retrieve a resource stream on the basis of the provided URI. The URI contains the location of the RTF document.
    7. Initialize a new StreamReader object with the obtained stream to read the entire RTF content of the stream to the end using the ReadToEnd method.
    8. Convert the RTF content into C1RichTextBox document using the ConvertToDocument method of the RtfFilter class. The C1RichTextbox control uses the Document method for this conversion.
    9. Display content in a print layout mode using the ViewMode property of the C1RichTextbox control to get an idea how the content appears when printed, as shown in the following code snippet:
      CS
      Copy Code
      var stream = Application.GetResourceStream(new Uri("./../Resources/MarkTwain.rtf", UriKind.RelativeOrAbsolute)).Stream;
      var rtf = new StreamReader(stream).ReadToEnd();
      rtb.Document = new RtfFilter().ConvertToDocument(rtf);
      rtb.ViewMode = TextViewMode.Print;         
      
           
      VB
      Copy Code
      Dim stream = Application.GetResourceStream(New Uri("./../Resources/MarkTwain.rtf", UriKind.Relative)).Stream           
      Dim rtf = New StreamReader(stream).ReadToEnd()
      rtb.Document = New RtfFilter().ConvertToDocument(rtf)
      rtb.ViewMode = TextViewMode.Print
      
           
    10. Add the following PageNumberConverter class to display page numbers from 1. The PageNumberConverter class uses the IValueConverter interface to convert integer page numbers into formatted strings for displaying footer messages. The IValueConverter interface contains Convert and ConvertBack methods for converting values from one type to another for data binding:
      CS
      Copy Code
      public class PageNumberConverter : IValueConverter
      {
          public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
          {
              if (value is int index)
              {
                  return $"{index + 1}";
              }
              return string.Empty;
          }
          public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
          {
              throw new NotImplementedException();
          }
      }
      
           
      VB
      Copy Code
      Public Class PageNumberConverter
          Implements IValueConverter
          Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
              If TypeOf value Is Integer Then
                  Dim index As Integer = DirectCast(value, Integer)
                  Return $"{index + 1}"
              End If
              Return String.Empty
          End Function
      
          Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
              Throw New NotImplementedException()
          End Function
      End Class
      
           

    On running the application, you can see header and footer on each page of the RTF document within the C1RichTextbox control.