フロー ドキュメントの概要

フロー ドキュメントは、表示と読みやすさを最適化するように設計されたドキュメントです。 フロー ドキュメントは、1 つの定義済みのレイアウトに設定するのではなく、ウィンドウのサイズ、デバイスの解像度、省略可能なユーザー設定など、ランタイム変数に基づいてコンテンツを動的に調整したりリフローしたりします。 また、フロー ドキュメントは、改ページ位置の自動修正や列などの高度なドキュメント機能を提供します。 ここでは、フロー ドキュメントの概要およびフロー ドキュメントの作成方法について説明します。

フロー ドキュメントとは

フロー ドキュメントは、ウィンドウ サイズ、デバイスの解像度、およびその他の環境変数に応じて "コンテンツをリフロー" するために設計されています。 また、フロー ドキュメントには、検索、読みやすさを最適化するモードの表示、およびフォントのサイズと外観を変更する機能を含むさまざまな組み込み機能があります。 フロー ドキュメントは、主なドキュメントの使用シナリオが読みやすさである場合に最適です。 これに対し、固定ドキュメントは、静的なプレゼンテーションを行うように設計されています。 ソース コンテンツの再現性が重要である場合は、固定ドキュメントが便利です。 各種ドキュメントの詳細については、「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 を使用したことがある場合、これは慣れ親しまれているでしょう。

フロー ドキュメントには、上の図で強調表示されているいくつかの機能が組み込まれています。

  • 検索: ユーザーがドキュメント全体のフル テキスト検索を実行できるようにします。

  • 表示モード: ユーザーは、単一ページ (一度に 1 ページ) 表示モード、一度に 2 ページ (読書形式) 表示モード、連続したスクロール (ボトムレス) 表示モードなど、各自に適切な表示モードを選択できます。 これらの表示モードの詳細については、「FlowDocumentReaderViewingMode」を参照してください。

  • ページ ナビゲーション コントロール: ドキュメントの表示モードでページを使用する場合、ページ ナビゲーション コントロールには、次のページへのジャンプ用ボタン (下向き矢印)、前のページへのジャンプ用ボタン (上向き矢印)、現在のページ番号と総ページ数のインジケーターが含まれます。 ページ間の移動は、キーボードの方向キーを使用して行うこともできます。

  • ズーム: ズーム コントロールでは、ユーザーはプラスまたはマイナス ボタンをそれぞれクリックして、ズーム レベルを上げたり下げたりすることができます。 ズーム コントロールには、ズーム レベルの調整用スライダーも含まれます。 詳細については、「Zoom」を参照してください。

これらの機能は、フロー コンテンツをホストするために使用されるコントロールに基づいて変更できます。 次のセクションでは、さまざまなコントロールについて説明します。

フロー ドキュメントの種類

フロー ドキュメント コンテンツの表示、およびそれがどのように表示されるかは、どのようなオブジェクトがフロー コンテンツをホストするために使用されるかに依存します。 フロー コンテンツの表示をサポートするコントロールには、FlowDocumentReaderFlowDocumentPageViewerRichTextBoxFlowDocumentScrollViewer の 4 つがあります。 これらのコントロールについて、以下に簡単に説明します。

注意

FlowDocument はフロー コンテンツを直接ホストするために必要です。したがって、これらの表示コントロールではすべて、フロー コンテンツ ホスティングを有効にするために FlowDocument を使用します。

FlowDocumentReader

FlowDocumentReader には、単一ページ (一度に 1 ページ) 表示モード、一度に 2 ページ (読書形式) 表示モード、連続スクロール (ボトムレス) 表示モードなど、さまざまな表示モードをユーザーが動的に選択できるようにする機能が含まれます。 これらの表示モードの詳細については、「FlowDocumentReaderViewingMode」を参照してください。 さまざまな表示モードを動的に切り替える必要がない場合、FlowDocumentPageViewer および FlowDocumentScrollViewer で、特定の表示モードに固定された軽量のフロー コンテンツ ビューアーが提供されます。

FlowDocumentPageViewer と FlowDocumentScrollViewer

FlowDocumentPageViewer では、コンテンツを一度に 1 ページの表示モードで表示しますが、FlowDocumentScrollViewer では、コンテンツを連続したスクロール モードで表示します。 FlowDocumentPageViewerFlowDocumentScrollViewer は両方とも、特定の表示モードに固定されています。 FlowDocumentReader と比較してください。これには、ユーザーが (FlowDocumentReaderViewingMode 列挙体で提供される) 各種表示モードから動的に選ぶことができる機能が含まれていますが、FlowDocumentPageViewerFlowDocumentScrollViewer よりも多くのリソースを消費します。

既定では、垂直スクロール バーは常に表示され、水平スクロール バーは必要に応じて表示されます。 IsToolBarVisible の既定の UI にはツール バーが含まれませんが、FlowDocumentScrollViewer プロパティを使用して組み込みツール バーを有効にできます。

RichTextBox

ユーザーがフロー コンテンツを編集できるようにする場合は、RichTextBox を使用します。 たとえば、テーブル、斜体や太字の書式設定などをユーザーが操作できるようにするエディターを作成する必要がある場合は、RichTextBox を使用します。 詳細については、「RichTextBox の概要」を参照してください。

注意

RichTextBox 内のフロー コンテンツは、他のコントロールに含まれているフロー コンテンツと一部異なる動作をします。 たとえば、RichTextBox に列がないと、自動サイズ変更動作は行われません。 また、検索、表示モード、ページ ナビゲーション、ズームなどのフロー コンテンツの通常の組み込み機能は、RichTextBox 内では利用できません。

フロー コンテンツの作成

フロー コンテンツは、テキスト、イメージ、テーブル、コントロールのような UIElement 派生クラスを含むさまざまな要素で構成された複雑なものにすることができます。 複雑なフロー コンテンツを作成する方法を理解するには、次の点が重要です。

  • フロー関連のクラス: フロー コンテンツで使用される各クラスには特定の目的があります。 また、フロー クラス間の階層型の関係により、それらがどのように使用されるかが理解しやすくなっています。 たとえば、Block から派生したクラスは他のオブジェクトを含めるために使用されますが、Inline クラスから派生したクラスには、表示されるオブジェクトが含まれます。

  • コンテンツ スキーマ: フロー ドキュメントには、多くの入れ子になった要素が必要になる場合があります。 コンテンツ スキーマは、使用可能な要素間の親/子リレーションシップを指定します。

以下のセクションでは、これらの各領域について詳しく説明します。

次の図は、フロー コンテンツで最も一般的に使用されるオブジェクトを示します。

Diagram: Flow content element class hierarchy

フロー コンテンツのために、次の 2 つの重要なカテゴリがあります。

  1. Block の派生クラス: "Block コンテンツ要素" または単に "Block 要素" とも呼ばれます。 Block から継承する要素は、要素を共通の親の下にグループ化したり、共通の属性をグループに適用したりするために使用できます。

  2. Inline の派生クラス: "Inline コンテンツ要素" または単に "Inline 要素" とも呼ばれます。 Inline から継承する要素は、Block 要素または別の Inline 要素内に格納されます。 Inline 要素は、多くの場合、画面にレンダリングされるコンテンツの直接のコンテナーとして使用されます。 たとえば、Paragraph (Block 要素) には Run (Inline 要素) を含めることができますが、Run には実際には、画面にレンダリングされるテキストが含まれます。

これらの 2 つのカテゴリの各クラスについて、以下に簡単に説明します。

Block の派生クラス

Paragraph

Paragraph は、通常、コンテンツを段落にグループ化するために使用されます。 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

しかし、次に示すように、他の Inline の派生要素を含めることもできます。

セクション

Section は、他の Block 派生要素を含めるためにのみ使用されます。 格納している要素に対して、既定の書式設定を適用することはありません。 しかし、Section に設定されたプロパティ値はすべて、その子要素に適用されます。 セクションでは、プログラムで子コレクションを反復処理することもできます。 Section は、HTML の <DIV> タグと同様の方法で使用されます。

以下の例では、3 つの段落が 1 つの 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 では、Block の派生フロー コンテンツに UIElement 要素 (つまり、Button) を埋め込めるようにします。 InlineUIContainer (下記参照) は、Inline の派生フロー コンテンツに UIElement 要素を埋め込むために使用されます。 BlockUIContainerInlineUIContainer は重要です。これら 2 つの要素のいずれかに含まれない限り、フロー コンテンツで 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

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 は、テーブルを作成するために使用されます。 TableGrid 要素に似ていますが、より多くの機能を備えているため、さらに多くのリソース オーバーヘッドが必要になります。 GridUIElement であるため、BlockUIContainer または InlineUIContainer に含まれている場合を除き、フロー コンテンツで使用することはできません。 Table の詳細については、「テーブルの概要」を参照してください。

Inline の派生クラス

実行

Run は、書式設定されていないテキストを含めるために使用されます。 フロー コンテンツでは、Run オブジェクトを広範に使用することを想定している場合があります。 しかし、マークアップでは、Run 要素を明示的に使用する必要はありません。 Run は、コードを使用してフロー ドキュメントを作成または操作するときに使用する必要があります。 たとえば、以下のマークアップでは、最初の ParagraphRun 要素が明示的に指定されますが、2 番目では指定されません。 両方の段落は、同じ出力を生成します。

<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 以降では、Run オブジェクトの Text プロパティは依存関係プロパティです。 TextBlock などのデータ ソースに、Text プロパティをバインドすることができます。 Text プロパティでは、一方向のバインドが完全にサポートされます。 Text プロパティでは、RichTextBox を除き、双方向のバインドもサポートされます。 例については、「Run.Text」を参照してください。

Span

Span では、他のインライン コンテンツ要素をまとめてグループ化します。 Span 要素内のコンテンツには、固有のレンダリングは適用されません。 しかし、HyperlinkBoldItalicUnderline を含め、Span から継承する要素では、書式設定がテキストに適用されます。

テキスト、Bold 要素、Button を含む、インライン コンテンツを含めるために使用されている Span の例を以下に示します。

<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 を使用して、ParagraphButton インラインを挿入する例を以下に示します。

<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 が作成されます。

Figure および Floater

FigureFloater は、主要コンテンツ フローとは別にカスタマイズできる配置プロパティを持つフロー ドキュメント内にコンテンツを埋め込むために使用されます。 多くの場合、Figure または Floater 要素は、コンテンツの一部を強調表示したり、目立たせたりするため、メイン コンテンツ フロー内のサポート イメージや他のコンテンツをホストするため、または広告などの関連の薄いコンテンツを挿入するために使用されます。

次の例では、テキストの段落に 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 はいくつかの点で異なり、異なるシナリオで使用されます。

Figure:

  • 配置可能です。水平方向および垂直方向のアンカーを設定することによって、ページ、コンテンツ、列または段落に対して相対的にドッキングできます。 また、HorizontalOffset および VerticalOffset プロパティを使用して、任意のオフセットを指定することもできます。

  • 複数の列にサイズを設定できます。Figure の高さと幅は、ページ、コンテンツ、または列の高さや幅の倍数に設定できます。 ページおよびコンテンツの場合は、1 より大きい倍数は指定できない点に注意してください。 たとえば、Figure の幅を "0.5 ページ"、"0.25 コンテンツ" または "2 列" に設定できます。 高さと幅は、絶対ピクセル値で指定することもできます。

  • ページ割り付けは行いません。Figure 内のコンテンツが Figure 内に収まらない場合は、収まるコンテンツがすべてレンダリングされ、残りのコンテンツは失われます

Floater:

  • 配置できません。必要なスペースを確保できる場所に描画されます。 Floater のオフセットやアンカーを設定することはできません。

  • 複数の列にサイズを設定することはできません。既定では、Floater のサイズは 1 列になります。 絶対ピクセル値に設定できる Width プロパティがありますが、この値が 1 列の幅より大きい場合は無視され、浮遊要素のサイズは 1 列になります。 正しいピクセル幅を設定することによってサイズを 1 列未満にすることはできますが、列を基準とした相対的なサイズ指定はできないため、Floater の幅に関しては "0.5 列" という表現は有効ではありません。 Floater には高さのプロパティはなく、高さを設定することはできません。高さはコンテンツに依存します

  • Floater ではページ割り付けを行います。指定された幅のコンテンツが複数列の高さまで拡張されると、浮遊要素は分割されて、次の列、次のページなどにページ割り付けが行われます

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"));

これにより、RunParagraphInlineCollection に追加されます。 これは、マークアップの Paragraph の内部にある暗黙の Run と同じです。

<Paragraph>
Some Text
</Paragraph>

BlockCollection の使用例として、次の例では新しい Section を作成してから、Add メソッドを使用して、新しい ParagraphSection コンテンツに追加します。

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 (インライン) と BlockCollection (ブロック) のどちらを使用するかは、親で含めることができる子要素の種類 (Block または Inline) によって異なります。 フロー コンテンツ要素のコンテインメイト規則については、次のセクションのコンテンツ スキーマにまとめます。

注意

フロー コンテンツで使用されるコレクションの 3 つ目の種類として 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. 図によると、ParagraphSectionTableListBlockUIContainer など、選択できる Block 要素がいくつかあります (上記の Block の派生クラスを参照)。 たとえば、Table が必要だとします。 上の図によると、Table には TableRowGroup が含まれており、それには TableRow 要素が含まれています。さらにこれには TableCell 要素が含まれており、それには Block の派生オブジェクトが含まれています。 上の図で 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 の下に 1 つまたは複数の Block 要素が必要です。 簡単にするために、セル内にいくつかのテキストを配置することにします。 これは、ParagraphRun 要素と共に使用することで行うことができます。 ParagraphInline 要素を受け取ることができ、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>

テキストのカスタマイズ

通常、テキストは、フロー ドキュメントで最も一般的なコンテンツの種類です。 上で導入されたオブジェクトは、テキストをレンダリングする方法のほとんどの側面を制御するために使用できますが、このセクションで説明されるテキストのカスタマイズ用にその他のメソッドがいくつか存在します。

文字装飾

文字装飾によって、下線、上線、ベースライン、および取り消し線の効果をテキストに適用できます (下図参照)。 これらの装飾は、InlineParagraphTextBlockTextBox を含む多数のオブジェクトによって公開される、TextDecorations プロパティを使用して追加されます。

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 を含むほとんどのフロー関連のコンテンツによって公開されます。 このプロパティは、テキストの文字体裁の特性またはバリエーション (つまり、小さい大文字か大きい大文字か、上付き文字と下付き文字の作成など) を制御するために使用されます。

次の例では、Paragraph を例の要素として使用して、Typography 属性を設定する方法が示されています。

<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 のタイポグラフィ」を参照してください。

関連項目