WPF: Flow Document

Friday 31 August 2012
Flow documents are designed to optimize viewing and readability. Rather than being set to one predefined layout, flow documents dynamically adjust and reflow their content based on run-time variables such as window size, device resolution, and optional user preferences. In addition, flow documents offer advanced document features, such as pagination and columns. 


What is a Flow Document
A flow document is designed to "reflow content" depending on window size, device resolution, and other environment variables. In addition, flow documents have a number of built in features including search, viewing modes that optimize readability, and the ability to change the size and appearance of fonts. Flow Documents are best utilized when ease of reading is the primary document consumption scenario. In contrast, Fixed Documents are designed to have a static presentation. Fixed Documents are useful when fidelity of the source content is essential.
The following illustration shows a sample flow document viewed in several windows of different sizes. As the display area changes, the content reflows to make the best use of the available space.




As seen in the image above, flow content can include many components including paragraphs, lists, images, and more. These components correspond to elements in markup and objects in procedural code. We will go over these classes in detail later in the Flow Related Classes section of this overview. For now, here is a simple code example that creates a flow document consisting of a paragraph with some bold text and a list.
XAML:
<!-- This simple flow document includes a paragraph with some bold text in it and a list. -->
<FlowDocumentReader xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <FlowDocument>
    <Paragraph>
      <Bold>Some bold text in the paragraph.</Bold>
      Some text that is not bold.
    </Paragraph>
    <List>
      <ListItem>
        <Paragraph>ListItem 1</Paragraph>
      </ListItem>
      <ListItem>
        <Paragraph>ListItem 2</Paragraph>
      </ListItem>
      <ListItem>
        <Paragraph>ListItem 3</Paragraph>
      </ListItem>
    </List>
  </FlowDocument>
</FlowDocumentReader>

C#
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace SDKSample
{
    public partial class SimpleFlowExample : Page
    {
        public SimpleFlowExample()
        {
          Paragraph myParagraph = new Paragraph();
          // Add some Bold text to the paragraph
          myParagraph.Inlines.Add(new Bold(new Run("Some bold text in the paragraph.")));

          // Add some plain text to the paragraph
          myParagraph.Inlines.Add(new Run(" Some text that is not bold."));

          // Create a List and populate with three list items.
          List myList = new List();

          // First create paragraphs to go into the list item.
          Paragraph paragraphListItem1 = new Paragraph(new Run("ListItem 1"));
          Paragraph paragraphListItem2 = new Paragraph(new Run("ListItem 2"));
          Paragraph paragraphListItem3 = new Paragraph(new Run("ListItem 3"));

          // Add ListItems with paragraphs in them.
          myList.ListItems.Add(new ListItem(paragraphListItem1));
          myList.ListItems.Add(new ListItem(paragraphListItem2));
          myList.ListItems.Add(new ListItem(paragraphListItem3));

         // Create a FlowDocument with the paragraph and list.
         FlowDocument myFlowDocument = new FlowDocument();
         myFlowDocument.Blocks.Add(myParagraph);
         myFlowDocument.Blocks.Add(myList);




         // Add the FlowDocument to a FlowDocumentReader Control
         FlowDocumentReader myFlowDocumentReader = new FlowDocumentReader();
         myFlowDocumentReader.Document = myFlowDocument;

         this.Content = myFlowDocumentReader;
       }
    }
}


The illustration below shows what this code snippet looks like.
 


In this example, the FlowDocumentReader control is used to host the flow content. See Flow Document Types for more information on flow content hosting controls. Paragraph, List, ListItem, and Bold elements are used to control content formatting, based on their order in markup. For example, the Bold element spans across only part of the text in the paragraph; as a result, only that part of the text is bold. If you have used HTML, this will be familiar to you.
As highlighted in the illustration above, there are several features built into Flow Documents:
  • Search: Allows the user to perform a full text search of an entire document.
  • Viewing Mode: The user can select their preferred viewing mode including a single-page (page-at-a-time) viewing mode, a two-page-at-a-time (book reading format) viewing mode, and a continuous scrolling (bottomless) viewing mode. For more information about these viewing modes, see FlowDocumentReaderViewingMode.
  • Page Navigation Controls: If the viewing mode of the document uses pages, the page navigation controls include a button to jump to the next page (the down arrow) or previous page (the up arrow), as well as indicators for the current page number and total number of pages. Flipping through pages can also be accomplished using the keyboard arrow keys.
  • Zoom: The zoom controls enable the user to increase or decrease the zoom level by clicking the plus or minus buttons, respectively. The zoom controls also include a slider for adjusting the zoom level. For more information, see Zoom.
These features can be modified based upon the control used to host the flow content. The next section describes the different controls.
Flow Document Types
Display of flow document content and how it appears is dependent upon what object is used to host the flow content. There are four controls that support viewing of flow content: FlowDocumentReader, FlowDocumentPageViewer, RichTextBox, and FlowDocumentScrollViewer. These controls are briefly described below.
Note:  FlowDocument is required to directly host flow content, so all of these viewing controls consume a FlowDocument to enable flow content hosting.
FlowDocumentReader
FlowDocumentReader includes features that enable the user to dynamically choose between various viewing modes, including a single-page (page-at-a-time) viewing mode, a two-page-at-a-time (book reading format) viewing mode, and a continuous scrolling (bottomless) viewing mode. For more information about these viewing modes, see FlowDocumentReaderViewingMode. If you do not need the ability to dynamically switch between different viewing modes, FlowDocumentPageViewer and FlowDocumentScrollViewer provide lighter-weight flow content viewers that are fixed in a particular viewing mode.
FlowDocumentPageViewer and FlowDocumentScrollViewer
FlowDocumentPageViewer shows content in page-at-a-time viewing mode, while FlowDocumentScrollViewer shows content in continuous scrolling mode. Both FlowDocumentPageViewer and FlowDocumentScrollViewer are fixed to a particular viewing mode. Compare to FlowDocumentReader, which includes features that enable the user to dynamically choose between various viewing modes (as provided by the FlowDocumentReaderViewingMode enumeration), at the cost of being more resource intensive than FlowDocumentPageViewer or FlowDocumentScrollViewer.
By default, a vertical scrollbar is always shown, and a horizontal scrollbar becomes visible if needed. The default UI for FlowDocumentScrollViewer does not include a toolbar; however, the IsToolBarVisible property can be used to enable a built-in toolbar.
RichTextBox
You use a RichTextBox when you want to allow the user to edit flow content. For example, if you wanted to create an editor that allowed a user to manipulate things like tables, italic and bold formatting, etc, you would use a RichTextBox. See RichTextBox Overview for more information.
Note: Flow content inside a RichTextBox does not behave exactly like flow content contained in other controls. For example, there are no columns in a RichTextBox and hence no automatic resizing behavior. Also, the typically built in features of flow content like search, viewing mode, page navigation, and zoom are not available within a RichTextBox.