非固定格式文件概觀

非固定格式文件的設計是為最佳化檢視和可讀性。 非固定格式文件並不會設為某種預先定義的配置,而是會根據執行階段變數 (例如視窗大小、裝置解析度和選擇性的使用者喜好設定),動態調整及自動重排其內容。 此外,非固定格式文件提供進階文件功能,例如編頁和資料行。 本主題提供非固定格式文件和建立方式的概觀。

什麼是非固定格式文件

非固定格式文件的設計是會根據視窗大小、裝置解析度及其他環境變數來「自動重排內容」。 此外,非固定格式文件具備許多內建功能,包括搜尋、將可讀性最佳化的檢視模式,以及變更字型大小與外觀的能力。 當可讀性是使用文件的主要考量時,最好使用非固定格式文件。 相反地,固定格式文件的設計是靜態展示。 當來源內容的精確度很重要時,固定格式文件很有用。 如需不同文件類型的詳細資訊,請參閱 WPF 中的文件

下圖顯示在數個不同大小的視窗中檢視非固定格式文件範例。 當顯示區域變更時,內容就會自動重排以充分利用可用的空間。

Flow Document Content Reflow

如上圖所示,非固定格式內容可以包含許多元件,包括段落、清單、映像等等。 這些元件會對應至程序性程式碼中標記和物件的項目。 稍後在本概觀的非固定格式相關的類別一節中,會詳述這些類別。 現在,先看看建立非固定格式文件的簡單程式碼範例,包含某些粗體文字的段落與清單。

<!-- 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>
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;
        }
    }
}

Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents

Namespace SDKSample
    Partial Public Class SimpleFlowExample
        Inherits Page
        Public Sub New()

            Dim myParagraph As 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.
            Dim myList As New List()

            ' First create paragraphs to go into the list item.
            Dim paragraphListItem1 As New Paragraph(New Run("ListItem 1"))
            Dim paragraphListItem2 As New Paragraph(New Run("ListItem 2"))
            Dim paragraphListItem3 As 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.
            Dim myFlowDocument As New FlowDocument()
            myFlowDocument.Blocks.Add(myParagraph)
            myFlowDocument.Blocks.Add(myList)

            ' Add the FlowDocument to a FlowDocumentReader Control
            Dim myFlowDocumentReader As New FlowDocumentReader()
            myFlowDocumentReader.Document = myFlowDocument

            Me.Content = myFlowDocumentReader
        End Sub
    End Class
End Namespace

下圖顯示此程式碼片段的外觀。

Screenshot: Rendered FlowDocument example

在此範例中 FlowDocumentReader ,控制項是用來裝載流程內容。 如需非固定格式內容裝載控制項的詳細資訊,請參閱非固定格式文件類型ParagraphListListItemBold 元素是用來根據內容格式設定,以標記的順序控制內容格式。 例如,元素 Bold 只會跨越段落中文字的一部分;因此,只有該部分的文字是粗體。 如果您使用過 HTML,會覺得很熟悉。

如上圖中的反白顯示,非固定格式文件有數項內建功能︰

  • 搜尋︰讓使用者對整份文件執行全文檢索搜尋。

  • 檢視模式︰使用者可以選取偏好的檢視模式,包括單一頁面 (一次一頁) 檢視模式、一次兩頁 (書本閱讀格式) 檢視模式,以及以連續捲動 (無底邊) 檢視模式。 如需這些檢視模式的詳細資訊,請參閱 FlowDocumentReaderViewingMode

  • 頁面導覽控制項︰如果文件的檢視模式使用頁面,則頁面導覽控制項會包括移至下一頁 (向下箭號) 或上一頁 (向上箭號) 的按鈕,以及目前頁碼和總頁數的指示器。 使用鍵盤方向鍵也可以翻頁。

  • 縮放︰縮放控制項可讓使用者按下加號或減號按鈕,分別放大或縮小縮放層級。 縮放控制項也包括調整縮放層級的滑桿。 如需詳細資訊,請參閱Zoom

您可以根據裝載非固定格式內容所用的控制項來修改這些功能。 下一節說明不同的控制項。

非固定格式文件類型

非固定格式文件內容的外觀和顯示方式,取決於裝載非固定格式內容的物件。 有四個控制項支援檢視流程內容: FlowDocumentReaderFlowDocumentPageViewerRichTextBoxFlowDocumentScrollViewer 。 以下簡短說明這些控制項。

注意

FlowDocument 是直接裝載流程內容的必要專案,因此所有這些檢視控制項都會取 FlowDocument 用 來啟用流程內容裝載。

FlowDocumentReader

FlowDocumentReader 包含可讓使用者動態選擇各種檢視模式的功能,包括單頁(一次分頁)檢視模式、一次兩頁(書籍閱讀格式)檢視模式,以及連續捲動(無底)檢視模式。 如需這些檢視模式的詳細資訊,請參閱 FlowDocumentReaderViewingMode 。 如果您不需要在不同檢視模式之間動態切換的能力, FlowDocumentPageViewer 並提供 FlowDocumentScrollViewer 在特定檢視模式中固定的較輕量流量內容檢視器。

FlowDocumentPageViewer 和 FlowDocumentScrollViewer

FlowDocumentPageViewer 會在一次頁面檢視模式中顯示內容,同時 FlowDocumentScrollViewer 以連續捲動模式顯示內容。 FlowDocumentPageViewerFlowDocumentScrollViewer 都固定為特定的檢視模式。 FlowDocumentReader與 比較 ,其中包含的功能可讓使用者動態選擇各種檢視模式(如 列舉所提供的 FlowDocumentReaderViewingMode ),代價是比 或 FlowDocumentScrollViewer 更耗 FlowDocumentPageViewer 用資源。

預設一定會顯示垂直捲軸,而水平捲動則會視需要顯示。 的預設 UI FlowDocumentScrollViewer 不包含工具列;不過, IsToolBarVisible 屬性可用來啟用內建工具列。

RichTextBox

RichTextBox當您想要允許使用者編輯流程內容時,請使用 。 例如,如果您想要建立編輯器,允許使用者運算元據表、斜體和粗體格式等專案,您可以使用 RichTextBox 。 如需詳細資訊,請參閱 RichTextBox 概觀

注意

內的 RichTextBox 流程內容的行為與其他控制項中包含的流程內容完全相同。 例如,中 RichTextBox 沒有任何資料行,因此不會自動調整大小行為。 此外,通常內建的流程內容功能,例如搜尋、檢視模式、頁面流覽和縮放,無法在 中使用 RichTextBox

建立非固定格式內容

流程內容可能相當複雜,包含各種元素,包括文字、影像、資料表,甚至是 UIElement 控制項等衍生類別。 若要了解如何建立複雜的非固定格式內容,下列幾點很重要︰

  • 非固定格式相關的類別:非固定格式內中使用的每種類別都有特定用途。 此外,非固定格式類別之間的階層式關聯性可協助您了解如何使用它們。 例如,衍生自 類別的 Block 類別可用來包含其他物件,而衍生自 Inline 的類別則包含顯示的物件。

  • 內容結構描述︰非固定格式文件會需要大量的巢狀項目。 內容結構描述指定項目之間可能的父/子關聯性。

下列各節會一一詳細介紹這些區域。

下圖顯示非固定格式內容中最常使用的物件︰

Diagram: Flow content element class hierarchy

針對非固定格式內容的目的,有兩個重要分類︰

  1. 區塊衍生類別︰也稱為「區塊內容項目」或簡稱為「區塊項目」。 繼承自 Block 的專案可用來將通用父代下的元素分組,或將通用屬性套用至群組。

  2. 內嵌衍生類別︰也稱為「內嵌內容項目」或簡稱為「內嵌項目」。 繼承自 Inline 的專案會包含在 Block 元素或其他內嵌元素內。 內嵌項目通常用為轉譯到螢幕之內容的直接容器。 例如, Paragraph [區塊元素] 可以包含 Run (Inline Element),但 Run 實際上包含在螢幕上轉譯的文字。

以下簡短描述這兩種分類中的每個類別。

區塊衍生類別

段落

Paragraph 通常用來將內容分組到段落中。 段落最簡單且最常見的用法是建立一段文字。

<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Paragraph>
    Some paragraph text.
  </Paragraph>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace SDKSample
{
    public partial class ParagraphExample : Page
    {
        public ParagraphExample()
        {

            // Create paragraph with some text.
            Paragraph myParagraph = new Paragraph();
            myParagraph.Inlines.Add(new Run("Some paragraph text."));

            // Create a FlowDocument and add the paragraph to it.
            FlowDocument myFlowDocument = new FlowDocument();
            myFlowDocument.Blocks.Add(myParagraph);

            this.Content = myFlowDocument;
        }
    }
}

Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents

Namespace SDKSample
    Partial Public Class ParagraphExample
        Inherits Page
        Public Sub New()

            ' Create paragraph with some text.
            Dim myParagraph As New Paragraph()
            myParagraph.Inlines.Add(New Run("Some paragraph text."))

            ' Create a FlowDocument and add the paragraph to it.
            Dim myFlowDocument As New FlowDocument()
            myFlowDocument.Blocks.Add(myParagraph)

            Me.Content = myFlowDocument
        End Sub
    End Class
End Namespace

不過,您也可以包含其他內嵌衍生元素,如下所示。

區段

Section 僅用於包含其他 Block 衍生元素。 它不會將任何預設的格式設定套用到其所包含的項目。 不過,在 上 Section 設定的任何屬性值都會套用至其子項目。 區段也可讓您以程式設計的方式逐一查看其子集合。 Section會以與 HTML 中的 DIV > 標記類似的方式 < 使用。

在下列範例中,三個段落定義在一個 Section 下。 區段的屬性值為 Background Red,因此段落的背景色彩也是紅色。

<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <!-- By default, Section applies no formatting to elements contained
       within it. However, in this example, the section has a Background
       property value of "Red", therefore, the three paragraphs (the block)  
       inside the section also have a red background. -->
  <Section Background="Red">
    <Paragraph>
      Paragraph 1
    </Paragraph>
    <Paragraph>
      Paragraph 2
    </Paragraph>
    <Paragraph>
      Paragraph 3
    </Paragraph>
  </Section>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;

namespace SDKSample
{
    public partial class SectionExample : Page
    {
        public SectionExample()
        {

            // Create three paragraphs
            Paragraph myParagraph1 = new Paragraph(new Run("Paragraph 1"));
            Paragraph myParagraph2 = new Paragraph(new Run("Paragraph 2"));
            Paragraph myParagraph3 = new Paragraph(new Run("Paragraph 3"));

            // Create a Section and add the three paragraphs to it.
            Section mySection = new Section();
            mySection.Background = Brushes.Red;

            mySection.Blocks.Add(myParagraph1);
            mySection.Blocks.Add(myParagraph2);
            mySection.Blocks.Add(myParagraph3);

            // Create a FlowDocument and add the section to it.
            FlowDocument myFlowDocument = new FlowDocument();
            myFlowDocument.Blocks.Add(mySection);

            this.Content = myFlowDocument;
        }
    }
}

Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Windows.Documents

Namespace SDKSample
    Partial Public Class SectionExample
        Inherits Page
        Public Sub New()

            ' Create three paragraphs
            Dim myParagraph1 As New Paragraph(New Run("Paragraph 1"))
            Dim myParagraph2 As New Paragraph(New Run("Paragraph 2"))
            Dim myParagraph3 As New Paragraph(New Run("Paragraph 3"))

            ' Create a Section and add the three paragraphs to it.
            Dim mySection As New Section()
            mySection.Background = Brushes.Red

            mySection.Blocks.Add(myParagraph1)
            mySection.Blocks.Add(myParagraph2)
            mySection.Blocks.Add(myParagraph3)

            ' Create a FlowDocument and add the section to it.
            Dim myFlowDocument As New FlowDocument()
            myFlowDocument.Blocks.Add(mySection)

            Me.Content = myFlowDocument
        End Sub
    End Class
End Namespace

BlockUIContainer

BlockUIContainer 可讓 UIElement 專案 (即 a Button ) 內嵌在區塊衍生的流程內容中。 InlineUIContainer (請參閱下方)用來將元素內 UIElement 嵌在內嵌衍生的流程內容中。 BlockUIContainerInlineUIContainer 很重要,因為除非它包含在這兩個元素的其中一個內,否則沒有其他方法可在 UIElement 流程內容中使用 。

下列範例示範如何使用 BlockUIContainer 元素在流程內容中裝載 UIElement 物件。

<FlowDocument ColumnWidth="400">
  <Section Background="GhostWhite">
    <Paragraph>
      A UIElement element may be embedded directly in flow content
      by enclosing it in a BlockUIContainer element.
    </Paragraph>
    <BlockUIContainer>
      <Button>Click me!</Button>
    </BlockUIContainer>
    <Paragraph>
      The BlockUIContainer element may host no more than one top-level
      UIElement.  However, other UIElements may be nested within the
      UIElement contained by an BlockUIContainer element.  For example,
      a StackPanel can be used to host multiple UIElement elements within
      a BlockUIContainer element.
    </Paragraph>
    <BlockUIContainer>
      <StackPanel>
        <Label Foreground="Blue">Choose a value:</Label>
        <ComboBox>
          <ComboBoxItem IsSelected="True">a</ComboBoxItem>
          <ComboBoxItem>b</ComboBoxItem>
          <ComboBoxItem>c</ComboBoxItem>
        </ComboBox>
        <Label Foreground ="Red">Choose a value:</Label>
        <StackPanel>
          <RadioButton>x</RadioButton>
          <RadioButton>y</RadioButton>
          <RadioButton>z</RadioButton>
        </StackPanel>
        <Label>Enter a value:</Label>
        <TextBox>
          A text editor embedded in flow content.
        </TextBox>
      </StackPanel>
    </BlockUIContainer>
  </Section>
</FlowDocument>

下圖顯示此範例的轉譯方式:

Screenshot that shows a UIElement embedded in flow content.

清單​​

List 是用來建立點符或數值清單。 將 MarkerStyle 屬性設定為 TextMarkerStyle 列舉值,以判斷清單的樣式。 下例示範如何建立簡單的清單。

<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <List>
    <ListItem>
      <Paragraph>
        List Item 1
      </Paragraph>
    </ListItem>
    <ListItem>
      <Paragraph>
        List Item 2
      </Paragraph>
    </ListItem>
    <ListItem>
      <Paragraph>
        List Item 3
      </Paragraph>
    </ListItem>
  </List>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;

namespace SDKSample
{
    public partial class ListExample : Page
    {
        public ListExample()
        {

            // Create three paragraphs
            Paragraph myParagraph1 = new Paragraph(new Run("List Item 1"));
            Paragraph myParagraph2 = new Paragraph(new Run("List Item 2"));
            Paragraph myParagraph3 = new Paragraph(new Run("List Item 3"));

            // Create the ListItem elements for the List and add the
            // paragraphs to them.
            ListItem myListItem1 = new ListItem();
            myListItem1.Blocks.Add(myParagraph1);
            ListItem myListItem2 = new ListItem();
            myListItem2.Blocks.Add(myParagraph2);
            ListItem myListItem3 = new ListItem();
            myListItem3.Blocks.Add(myParagraph3);

            // Create a List and add the three ListItems to it.
            List myList = new List();

            myList.ListItems.Add(myListItem1);
            myList.ListItems.Add(myListItem2);
            myList.ListItems.Add(myListItem3);

            // Create a FlowDocument and add the section to it.
            FlowDocument myFlowDocument = new FlowDocument();
            myFlowDocument.Blocks.Add(myList);

            this.Content = myFlowDocument;
        }
    }
}

Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Windows.Documents

Namespace SDKSample
    Partial Public Class ListExample
        Inherits Page
        Public Sub New()

            ' Create three paragraphs
            Dim myParagraph1 As New Paragraph(New Run("List Item 1"))
            Dim myParagraph2 As New Paragraph(New Run("List Item 2"))
            Dim myParagraph3 As New Paragraph(New Run("List Item 3"))

            ' Create the ListItem elements for the List and add the 
            ' paragraphs to them.
            Dim myListItem1 As New ListItem()
            myListItem1.Blocks.Add(myParagraph1)
            Dim myListItem2 As New ListItem()
            myListItem2.Blocks.Add(myParagraph2)
            Dim myListItem3 As New ListItem()
            myListItem3.Blocks.Add(myParagraph3)

            ' Create a List and add the three ListItems to it.
            Dim myList As New List()

            myList.ListItems.Add(myListItem1)
            myList.ListItems.Add(myListItem2)
            myList.ListItems.Add(myListItem3)

            ' Create a FlowDocument and add the section to it.
            Dim myFlowDocument As New FlowDocument()
            myFlowDocument.Blocks.Add(myList)

            Me.Content = myFlowDocument
        End Sub
    End Class
End Namespace

注意

List 是唯一使用 ListItemCollection 來管理子專案的流程專案。

Table

Table 是用來建立資料表。 TableGrid 元素類似,但它具有更多功能,因此需要更大的資源額外負荷。 因為 GridUIElement ,除非它包含在 或 InlineUIContainerBlockUIContainer ,否則它不能用於流程內容中。 如需 的詳細資訊 Table ,請參閱 資料表概觀

內嵌衍生類別

執行

Run 是用來包含未格式化的文字。 您可能會預期 Run 物件會在流程內容中廣泛使用。 不過,在標記中, Run 不需要明確使用元素。 Run 必須使用程式碼建立或操作流程檔。 例如,在下列標記中,第一個 Paragraph 會明確指定 Run 元素,而第二個則不會。 這兩個段落會產生相同的輸出。

<Paragraph>
  <Run>Paragraph that explicitly uses the Run element.</Run>
</Paragraph>

<Paragraph>
  This Paragraph omits the Run element in markup. It renders
  the same as a Paragraph with Run used explicitly. 
</Paragraph>

注意

從 .NET Framework 4 開始, Text 物件的 屬性 Run 是相依性屬性。 您可以將 屬性系結 Text 至資料來源,例如 TextBlock 。 屬性 Text 完全支援單向系結。 屬性 Text 也支援雙向系結,但 除外 RichTextBox 。 如需範例,請參閱 Run.Text

Span

Span 將其他內嵌內容元素群組在一起。 不會將固有轉 Span 譯套用至元素內的內容。 不過,繼承自 Span 的專案包括 HyperlinkBoldItalicUnderline 會套用格式化至文字。

以下是用來包含內嵌內容的範例 Span ,包括文字、 Bold 專案和 Button

<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Paragraph>
    Text before the Span. <Span Background="Red">Text within the Span is
    red and <Bold>this text is inside the Span-derived element Bold.</Bold>
    A Span can contain more then text, it can contain any inline content. For
    example, it can contain a 
    <InlineUIContainer>
      <Button>Button</Button>
    </InlineUIContainer>
    or other UIElement, a Floater, a Figure, etc.</Span>
  </Paragraph>

</FlowDocument>

以下的螢幕擷取畫面顯示此範例的轉譯方式。

Screenshot: Rendered Span example

InlineUIContainer

InlineUIContainer 可讓 UIElement 元素 (亦即類似 Button 的控制項) 內嵌在內容元素中 Inline 。 此元素相當於上述的內嵌 BlockUIContainer 。 以下是用來 InlineUIContainer 在 中插入 Button 內嵌的 Paragraph 範例。

<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Paragraph>
    Text to precede the button...

    <!-- Set the BaselineAlignment property to "Bottom" 
         so that the Button aligns properly with the text. -->
    <InlineUIContainer BaselineAlignment="Bottom">
      <Button>Button</Button>
    </InlineUIContainer>
    Text to follow the button...
  </Paragraph>

</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;

namespace SDKSample
{
    public partial class InlineUIContainerExample : Page
    {
        public InlineUIContainerExample()
        {
            Run run1 = new Run(" Text to precede the button... ");
            Run run2 = new Run(" Text to follow the button... ");

            // Create a new button to be hosted in the paragraph.
            Button myButton = new Button();
            myButton.Content = "Click me!";

            // Create a new InlineUIContainer to contain the Button.
            InlineUIContainer myInlineUIContainer = new InlineUIContainer();

            // Set the BaselineAlignment property to "Bottom" so that the
            // Button aligns properly with the text.
            myInlineUIContainer.BaselineAlignment = BaselineAlignment.Bottom;

            // Asign the button as the UI container's child.
            myInlineUIContainer.Child = myButton;

            // Create the paragraph and add content to it.
            Paragraph myParagraph = new Paragraph();
            myParagraph.Inlines.Add(run1);
            myParagraph.Inlines.Add(myInlineUIContainer);
            myParagraph.Inlines.Add(run2);

            // Create a FlowDocument and add the paragraph to it.
            FlowDocument myFlowDocument = new FlowDocument();
            myFlowDocument.Blocks.Add(myParagraph);

            this.Content = myFlowDocument;
        }
    }
}

Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Windows.Documents

Namespace SDKSample
    Partial Public Class InlineUIContainerExample
        Inherits Page
        Public Sub New()
            Dim run1 As New Run(" Text to precede the button... ")
            Dim run2 As New Run(" Text to follow the button... ")

            ' Create a new button to be hosted in the paragraph.
            Dim myButton As New Button()
            myButton.Content = "Click me!"

            ' Create a new InlineUIContainer to contain the Button.
            Dim myInlineUIContainer As New InlineUIContainer()

            ' Set the BaselineAlignment property to "Bottom" so that the 
            ' Button aligns properly with the text.
            myInlineUIContainer.BaselineAlignment = BaselineAlignment.Bottom

            ' Asign the button as the UI container's child.
            myInlineUIContainer.Child = myButton

            ' Create the paragraph and add content to it.
            Dim myParagraph As New Paragraph()
            myParagraph.Inlines.Add(run1)
            myParagraph.Inlines.Add(myInlineUIContainer)
            myParagraph.Inlines.Add(run2)

            ' Create a FlowDocument and add the paragraph to it.
            Dim myFlowDocument As New FlowDocument()
            myFlowDocument.Blocks.Add(myParagraph)

            Me.Content = myFlowDocument
        End Sub
    End Class
End Namespace

注意

InlineUIContainer 不需要在標記中明確使用。 如果您省略它, InlineUIContainer 在編譯器代碼時,還是會建立 。

圖表和 Floater

FigureFloater 是用來將內容內嵌在 Flow Documents 中,其放置屬性可獨立于主要內容流程而自訂。 FigureFloater 元素通常用來反白顯示或強調部分內容、裝載支援影像或主要內容流程內的其他內容,或插入鬆散相關的內容,例如廣告。

下列範例示範如何將 內嵌 Figure 至文欄位落。

<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Paragraph>
    <Figure 
      Width="300" Height="100" 
      Background="GhostWhite" HorizontalAnchor="PageLeft" >
      <Paragraph FontStyle="Italic" Background="Beige" Foreground="DarkGreen" >
        A Figure embeds content into flow content with placement properties 
        that can be customized independently from the primary content flow
      </Paragraph>
    </Figure>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy
    nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi
    enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis
    nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
  </Paragraph>

</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;

namespace SDKSample
{
    public partial class FigureExample : Page
    {
        public FigureExample()
        {

            // Create strings to use as content.
            string strFigure = "A Figure embeds content into flow content with" +
                               " placement properties that can be customized" +
                               " independently from the primary content flow";
            string strOther = "Lorem ipsum dolor sit amet, consectetuer adipiscing" +
                              " elit, sed diam nonummy nibh euismod tincidunt ut laoreet" +
                              " dolore magna aliquam erat volutpat. Ut wisi enim ad" +
                              " minim veniam, quis nostrud exerci tation ullamcorper" +
                              " suscipit lobortis nisl ut aliquip ex ea commodo consequat." +
                              " Duis autem vel eum iriure.";

            // Create a Figure and assign content and layout properties to it.
            Figure myFigure = new Figure();
            myFigure.Width = new FigureLength(300);
            myFigure.Height = new FigureLength(100);
            myFigure.Background = Brushes.GhostWhite;
            myFigure.HorizontalAnchor = FigureHorizontalAnchor.PageLeft;
            Paragraph myFigureParagraph = new Paragraph(new Run(strFigure));
            myFigureParagraph.FontStyle = FontStyles.Italic;
            myFigureParagraph.Background = Brushes.Beige;
            myFigureParagraph.Foreground = Brushes.DarkGreen;
            myFigure.Blocks.Add(myFigureParagraph);

            // Create the paragraph and add content to it.
            Paragraph myParagraph = new Paragraph();
            myParagraph.Inlines.Add(myFigure);
            myParagraph.Inlines.Add(new Run(strOther));

            // Create a FlowDocument and add the paragraph to it.
            FlowDocument myFlowDocument = new FlowDocument();
            myFlowDocument.Blocks.Add(myParagraph);

            this.Content = myFlowDocument;
        }
    }
}

Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Windows.Documents

Namespace SDKSample
    Partial Public Class FigureExample
        Inherits Page
        Public Sub New()

            ' Create strings to use as content.
            Dim strFigure As String = "A Figure embeds content into flow content with" & " placement properties that can be customized" & " independently from the primary content flow"
            Dim strOther As String = "Lorem ipsum dolor sit amet, consectetuer adipiscing" & " elit, sed diam nonummy nibh euismod tincidunt ut laoreet" & " dolore magna aliquam erat volutpat. Ut wisi enim ad" & " minim veniam, quis nostrud exerci tation ullamcorper" & " suscipit lobortis nisl ut aliquip ex ea commodo consequat." & " Duis autem vel eum iriure."

            ' Create a Figure and assign content and layout properties to it.
            Dim myFigure As New Figure()
            myFigure.Width = New FigureLength(300)
            myFigure.Height = New FigureLength(100)
            myFigure.Background = Brushes.GhostWhite
            myFigure.HorizontalAnchor = FigureHorizontalAnchor.PageLeft
            Dim myFigureParagraph As New Paragraph(New Run(strFigure))
            myFigureParagraph.FontStyle = FontStyles.Italic
            myFigureParagraph.Background = Brushes.Beige
            myFigureParagraph.Foreground = Brushes.DarkGreen
            myFigure.Blocks.Add(myFigureParagraph)

            ' Create the paragraph and add content to it.
            Dim myParagraph As New Paragraph()
            myParagraph.Inlines.Add(myFigure)
            myParagraph.Inlines.Add(New Run(strOther))

            ' Create a FlowDocument and add the paragraph to it.
            Dim myFlowDocument As New FlowDocument()
            myFlowDocument.Blocks.Add(myParagraph)

            Me.Content = myFlowDocument
        End Sub
    End Class
End Namespace

下圖顯示此範例的轉譯方式。

Screenshot: Figure example

FigureFloater 在數種方式中不同,並用於不同的案例。

圖表:

  • 可以定位︰可以設定其水平和垂直錨點,將它固定在頁面、內容、資料行或段落的相對位置。 您也可以使用其 HorizontalOffsetVerticalOffset 屬性來指定任意位移。

  • 可調整為多個資料行的大小:您可以將高度和寬度設定 Figure 為頁面、內容或欄高度或寬度的倍數。 請注意,如果是頁面及內容,倍數不能大於 1。 例如,您可以將 的 Figure 寬度設定為 「0.5 page」 或 「0.25 content」 或 「2 Column」。 您也可以將高度和寬度設為絕對像素值。

  • 不分頁:如果 內 Figure 的內容不符合 內 Figure ,則會轉譯任何符合的內容,而剩餘的內容會遺失

Floater:

  • 無法定位,但會轉譯任何可用的空間。 您無法設定位移或錨定 Floater

  • 無法調整為一個以上的資料行大小:根據預設, Floater 一個資料行的大小。 它有一個 Width 屬性,可以設定為絕對圖元值,但如果這個值大於一欄寬度,則會忽略它,而浮點數則是在一個資料行上調整大小。 您可以藉由設定正確的圖元寬度來將其大小調整為小於一欄,但調整大小不是資料行相對,因此 「0.5Column」 不是寬度的有效運算式 FloaterFloater 沒有 height 屬性且高度無法設定,高度取決於內容

  • Floater 分頁:如果其內容在指定的寬度延伸至超過 1 欄高度,浮點符會中斷並分頁至下一個資料行、下一頁等等。

Figure 是放置獨立內容的絕佳位置,您想要控制大小和位置,並確信內容會符合指定的大小。 Floater 是放置更多與主頁面內容類別似的自由流動內容,但與主頁面內容分開的好位置。

LineBreak

LineBreak 會導致流程內容發生分行符號。 下列範例示範 LineBreak 的用法。

<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Paragraph>
    Before the LineBreak in Paragraph.
    <LineBreak />
    After the LineBreak in Paragraph.
    <LineBreak/><LineBreak/>
    After two LineBreaks in Paragraph.
  </Paragraph>

  <Paragraph>
    <LineBreak/>
  </Paragraph>

  <Paragraph>
    After a Paragraph with only a LineBreak in it.
  </Paragraph>
</FlowDocument>

以下的螢幕擷取畫面顯示此範例的轉譯方式。

Screenshot: LineBreak example

流程集合項目

在上述許多範例中, BlockCollectionInlineCollection 是用來以程式設計方式建構流程內容。 例如,若要將元素新增至 Paragraph ,您可以使用 語法:

myParagraph.Inlines.Add(new Run("Some text"));

這會將 加入 RunInlineCollectionParagraph 。 這與在 標記中找到 Paragraph 的隱含 Run 相同:

<Paragraph>
Some Text
</Paragraph>

作為 使用 BlockCollection 的範例,下列範例會建立新的 Section ,然後使用 Add 方法將新的 Paragraph 新增至 Section 內容。

Section secx = new Section();
secx.Blocks.Add(new Paragraph(new Run("A bit of text content...")));
Dim secx As New Section()
secx.Blocks.Add(New Paragraph(New Run("A bit of text content...")))

除了將項目新增至流程集合,您也可以移除項目。 下列範例會刪除 中的 Span 最後一個專案 Inline

spanx.Inlines.Remove(spanx.Inlines.LastInline);
spanx.Inlines.Remove(spanx.Inlines.LastInline)

下列範例會清除 Span 中的所有內容( Inline 專案)。

spanx.Inlines.Clear();
spanx.Inlines.Clear()

以程式設計方式處理非固定格式內容時,您可能也會廣泛使用這些集合。

流程專案是否使用 InlineCollection (Inlines) 或 BlockCollection [區塊] 來包含其子專案,取決於父代可以包含的子專案類型。 BlockInline 下一節的<內容結構描述>會摘要說明非固定格式內容項目的內含項目規則。

注意

有第三種類型的集合與流程內容搭配使用, ListItemCollection 但這個集合只搭配 使用 List 。 此外,還有數個集合搭配 使用 Table 。 如需詳細資訊,請參閱資料表概觀

內容結構描述

假設有多種不同的非固定格式內容項目,追蹤項目可以包含哪些子項目類型可能很累人。 下圖摘要說明流程項目的內含項目規則。 箭號代表可能的父/子關聯性。

Diagram: Flow content containment schema

如上圖所示,允許元素的子系不一定取決於它是 Block 元素還是 Inline 專案。 例如, Span (元素 Inline )只能有 Inline 子專案,而 Figure (也元素 Inline ) 只能有 Block 子專案。 因此,可以快速判斷哪些項目可以包含其他項目的圖表就很有用。 例如,讓我們使用圖表來判斷如何建構 的 RichTextBox 流程內容。

1. RichTextBox 必須包含 FlowDocument ,而 後者必須包含 Block 衍生的物件。 以下是來自上圖的對應區段。

Diagram: RichTextBox containment rules

這是標記目前可能的樣子。

<RichTextBox>
  <FlowDocument>
    <!-- One or more Block-derived object… -->
  </FlowDocument>
</RichTextBox>

2. 根據圖表,有數 Block 個元素可供選擇,包括 ParagraphSectionTableListBlockUIContainer (請參閱上述區塊衍生類別)。 假設我們想要 。 Table 根據上圖,包含 TableTableRowGroup 包含的 TableRow 元素,其中包含包含 TableCellBlock 衍生物件的專案。 以下是從上圖擷取的對應區段 Table

Diagram: Parent/child schema for Table

以下是對應的標記。

<RichTextBox>
  <FlowDocument>
    <Table>
      <TableRowGroup>
        <TableRow>
          <TableCell>
            <!-- One or more Block-derived object… -->
          </TableCell>
        </TableRow>
      </TableRowGroup>
    </Table>
  </FlowDocument>
</RichTextBox>

3. 同樣地,在 下方 TableCell 需要一或多個 Block 元素。 為求簡便,我們在儲存格中放入一些文字。 我們可以使用 搭配 Run 專案來執行這項 Paragraph 操作。 以下是圖表中對應的區段,其中顯示 Paragraph 可以採用 Inline 元素,而 Run (元素 Inline ) 只能採用純文字。

Diagram: Parent/child schema for Paragraph

Diagram: Parent/Child schema for Run

以下是標記的完整範例。

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <RichTextBox>
    <FlowDocument>
      
      <!-- Normally a table would have multiple rows and multiple
           cells but this code is for demonstration purposes.-->
      <Table>
        <TableRowGroup>
          <TableRow>
            <TableCell>
              <Paragraph>

                <!-- The schema does not actually require
                     explicit use of the Run tag in markup. It 
                     is only included here for clarity. -->
                <Run>Paragraph in a Table Cell.</Run>
              </Paragraph>
            </TableCell>
          </TableRow>
        </TableRowGroup>
      </Table>

    </FlowDocument>
  </RichTextBox>
</Page>

自訂文字

文字通常是非固定格式文件中最普遍的內容類型。 雖然您可以使用前文介紹的物件控制大部分的文字轉譯方式,但有一些其他方法可處理本節討論的自訂文字。

文字裝飾

文字裝飾讓您對文字套用底線、頂線、基準線及刪除線效果 (請參閱下圖)。 這些裝飾是使用 TextDecorations 由許多物件公開的屬性來新增的,包括 InlineParagraphTextBlockTextBox

下列範例示範如何設定 TextDecorationsParagraph 屬性。

<FlowDocument ColumnWidth="200">
  <Paragraph TextDecorations="Strikethrough">
    This text will render with the strikethrough effect.
  </Paragraph>
</FlowDocument>
Paragraph parx = new Paragraph(new Run("This text will render with the strikethrough effect."));
parx.TextDecorations = TextDecorations.Strikethrough;
Dim parx As New Paragraph(New Run("This text will render with the strikethrough effect."))
parx.TextDecorations = TextDecorations.Strikethrough

下圖顯示此範例的轉譯方式。

Screenshot: Text with default strikethrough effect

下列圖片分別顯示轉譯的頂線基準線底線裝飾。

Screenshot: Overline TextDecorator

Screenshot: Default baseline effect on text

Screenshot: Text with default underline effect

印刷樣式

屬性 Typography 是由大部分的流程相關內容所公開,包括 TextElementFlowDocumentTextBlockTextBox 。 這個屬性是用來控制文字的印刷特性/變化 (即小型或大型大寫字、上標和下標等等)。

下列範例示範如何使用 作為範例專案來設定 Typography 屬性 Paragraph

<Paragraph
  TextAlignment="Left"
  FontSize="18" 
  FontFamily="Palatino Linotype"
  Typography.NumeralStyle="OldStyle"
  Typography.Fraction="Stacked"
  Typography.Variants="Inferior"
>
  <Run>
    This text has some altered typography characteristics.  Note
    that use of an open type font is necessary for most typographic
    properties to be effective.
  </Run>
  <LineBreak/><LineBreak/>
  <Run>
    0123456789 10 11 12 13
  </Run>
  <LineBreak/><LineBreak/>
  <Run>
    1/2 2/3 3/4
  </Run>
</Paragraph>

下圖顯示此範例的轉譯方式。

Screenshot showing text with altered typography.

相反地,下圖顯示如何轉譯套用預設印刷樣式屬性的類似範例。

Screenshot showing text with default typography.

下列範例示範如何以程式設計方式設定 Typography 屬性。

Paragraph par = new Paragraph();

Run runText = new Run(
    "This text has some altered typography characteristics.  Note" +
    "that use of an open type font is necessary for most typographic" +
    "properties to be effective.");
Run runNumerals = new Run("0123456789 10 11 12 13");
Run runFractions = new Run("1/2 2/3 3/4");

par.Inlines.Add(runText);
par.Inlines.Add(new LineBreak());
par.Inlines.Add(new LineBreak());
par.Inlines.Add(runNumerals);
par.Inlines.Add(new LineBreak());
par.Inlines.Add(new LineBreak());
par.Inlines.Add(runFractions);

par.TextAlignment = TextAlignment.Left;
par.FontSize = 18;
par.FontFamily = new FontFamily("Palatino Linotype");

par.Typography.NumeralStyle = FontNumeralStyle.OldStyle;
par.Typography.Fraction = FontFraction.Stacked;
par.Typography.Variants = FontVariants.Inferior;
Dim par As New Paragraph()

Dim runText As New Run("This text has some altered typography characteristics.  Note" & "that use of an open type font is necessary for most typographic" & "properties to be effective.")
Dim runNumerals As New Run("0123456789 10 11 12 13")
Dim runFractions As New Run("1/2 2/3 3/4")

par.Inlines.Add(runText)
par.Inlines.Add(New LineBreak())
par.Inlines.Add(New LineBreak())
par.Inlines.Add(runNumerals)
par.Inlines.Add(New LineBreak())
par.Inlines.Add(New LineBreak())
par.Inlines.Add(runFractions)

par.TextAlignment = TextAlignment.Left
par.FontSize = 18
par.FontFamily = New FontFamily("Palatino Linotype")

par.Typography.NumeralStyle = FontNumeralStyle.OldStyle
par.Typography.Fraction = FontFraction.Stacked
par.Typography.Variants = FontVariants.Inferior

如需印刷樣式的詳細資訊,請參閱 WPF 中的印刷樣式

另請參閱