Share via


Übersicht über Flussdokumente

Aktualisiert: November 2007

Flussdokumente sollen die Anzeige und die Lesbarkeit optimieren. Flussdokumente sind nicht auf ein vordefiniertes Layout festgelegt, sondern passen Inhalte dynamisch an und bauen sie neu auf. Dies geschieht auf der Basis von Laufzeitvariablen, wie z. B. Fenstergröße, Geräteauflösung und optionalen Benutzereinstellungen. Außerdem bieten Flussdokumente erweiterte Dokumentfeatures, z. B. Paginierung und Spalten. Dieses Thema enthält eine Übersicht über Flussdokumente und deren Erstellung.

Dieses Thema enthält folgende Abschnitte.

  • Was ist ein Flussdokument?
  • Flussdokumenttypen
  • Erstellen von fortlaufendem Inhalt
  • Flussbezogene Klassen
  • Inhaltsschema
  • Anpassen von Text
  • Verwandte Abschnitte

Was ist ein Flussdokument?

Ein Flussdokument soll Inhalte abhängig von der Fenstergröße, der Geräteauflösung und anderen Umgebungsvariablen "neu aufbauen". Zusätzlich besitzen Flussdokumente eine Anzahl integrierter Features, darunter Suchfunktionen, Anzeigemodi, mit denen die Lesbarkeit verbessert wird, und die Fähigkeit, die Größe und die Darstellung von Schriftarten zu ändern. Die besten Ergebnisse mit Flussdokumenten werden erzielt, wenn es darum geht, dass Benutzer das Dokument besser lesen können. Bei einheitlich dargestellten Dokumenten geht es im Gegensatz dazu um die statische Darstellung. Einheitlich dargestellte Dokumente sind nützlich, wenn eine originalgetreue Wiedergabe des Inhalts der Quelldatei gewünscht wird. Weitere Informationen über unterschiedliche Dokumenttypen finden Sie unter Dokumente in Windows Presentation Foundation.

Die folgende Abbildung zeigt ein Beispielflussdokument, das in mehreren Fenstern mit verschiedenen Größen angezeigt wird. Wenn sich der Anzeigebereich ändert, wird der Inhalt neu angeordnet, um den verfügbaren Platz optimal zu nutzen.

Flussdokument-Inhalt, geänderte Flussrichtung

Wie im Bild oben gezeigt, kann der fortlaufende Inhalt viele verschiedene Komponenten enthalten, unter anderem Absätze, Listen und Bilder. Diese Komponenten entsprechen Elementen in Markup und Objekten in Verfahrenscode. Diese Klassen werden später im Abschnitt Flussbezogene Klassen dieses Überblicks ausführlich beschrieben. Hier folgt zunächst ein einfaches Codebeispiel, in dem ein Flussdokument erstellt wird, das aus einem Absatz mit teilweise fett formatiertem Text und einer Liste besteht.

<!-- This simple flow document includes a paragraph with some
     bold text in it and a list. -->
<FlowDocumentReader xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://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;
        }
    }
}

Die folgende Abbildung zeigt, wie dieser Codeausschnitt aussieht.

Bildschirmabbildung: Gerendertes FlowDocument-Beispiel

In diesem Beispiel wird das FlowDocumentReader-Steuerelement verwendet, um den fortlaufenden Inhalt zu hosten. Weitere Informationen über Steuerelemente zum Hosten von fortlaufendem Inhalt finden Sie in Flussdokumenttypen. Die Elemente Paragraph, List, ListItem und Bold werden verwendet, um abhängig von ihrer Reihenfolge im Markup die Formatierung des Inhalts zu steuern. So umspannt das Bold-Element nur einen Teil des Texts im Abschnitt, und folglich wird nur dieser Teil des Texts fett formatiert. Wenn Sie HTML verwendet haben, ist Ihnen dies bekannt.

Wie in der Abbildung oben hervorgehoben, gibt es mehrere in Flussdokumenten integrierte Features:

  • Suche: Ermöglicht es dem Benutzer, eine Volltextsuche in einem ganzen Dokument auszuführen.

  • Anzeigemodus: Der Benutzer kann seinen bevorzugten Anzeigemodus auswählen. Dazu gehören ein einseitiger (jeweils einzelne Seiten) Anzeigemodus, ein Anzeigemodus mit zwei Seiten gleichzeitig (Buchformat) und ein Anzeigemodus mit fortlaufendem (randlosem) Bildlauf. Weitere Informationen zu diesen Anzeigemodi finden Sie unter FlowDocumentReaderViewingMode.

  • Steuerelemente für die Seitennavigation: Wenn der Anzeigemodus des Dokuments Seiten verwendet, gehören zu den Steuerelementen für die Seitennavigation eine Schaltfläche für das Wechseln zur nächsten Seite (Pfeil nach unten) oder zur vorherigen Seite (Pfeil nach oben) sowie Anzeigen für die aktuelle Seitenzahl und die Gesamtseitenzahl. Auch mit den Tastaturpfeiltasten kann durch Seiten geblättert werden.

  • Zoom: Die Zoomsteuerelemente ermöglichen Benutzern das Vergrößern oder Verkleinern der Zoomstufe durch Klicken auf die Schaltfläche mit dem Plus- bzw. dem Minuszeichen. Die Zoomsteuerelemente enthalten außerdem einen Schieberegler zum Anpassen der Zoomstufe. Weitere Informationen finden Sie unter Zoom.

Diese Features können abhängig von dem Steuerelement geändert werden, das verwendet wird, um den fortlaufenden Inhalt zu hosten. Im nächsten Abschnitt werden die verschiedenen Steuerelemente beschrieben.

Flussdokumenttypen

Die Darstellung und die Anzeige des Inhalts von Flussdokumenten hängen davon ab, welches Objekt verwendet wird, um den fortlaufenden Inhalt zu hosten. Es gibt vier Steuerelemente, die das Anzeigen von Flussinhalt unterstützen: FlowDocumentReader, FlowDocumentPageViewer, RichTextBox und FlowDocumentScrollViewer. Diese Steuerelemente werden unten kurz beschrieben.

Hinweis: FlowDocument ist erforderlich, um fortlaufenden Inhalt direkt zu hosten. All diese Anzeigesteuerelemente verwenden somit FlowDocument, um das Hosten von fortlaufendem Inhalt zu ermöglichen.

FlowDocumentReader

FlowDocumentReader enthält Features, mit denen Benutzer dynamisch zwischen verschiedenen Anzeigemodi auswählen können. Dazu gehören ein einseitiger (jeweils einzelne Seiten) Anzeigemodus, ein Anzeigemodus mit zwei Seiten gleichzeitig (Buchformat) und ein Anzeigemodus mit fortlaufendem (randlosem) Bildlauf. Weitere Informationen zu diesen Anzeigemodi finden Sie unter FlowDocumentReaderViewingMode. Wenn keine dynamischen Wechsel zwischen den unterschiedlichen Anzeigemodi erforderlich sind, bieten FlowDocumentPageViewer und FlowDocumentScrollViewer auch weniger umfangreiche Anzeigen für fortlaufenden Inhalt, die auf einen bestimmten Anzeigemodus festgelegt sind.

FlowDocumentPageViewer und FlowDocumentScrollViewer

FlowDocumentPageViewer zeigt Inhalt im einseitigen Anzeigemodus an, während FlowDocumentScrollViewer Inhalt im fortlaufenden Bildlaufmodus anzeigt. Sowohl FlowDocumentPageViewer als auch FlowDocumentScrollViewer sind auf einen bestimmten Anzeigemodus festgelegt. Im Gegensatz dazu bietet FlowDocumentReader Features für die dynamische Auswahl verschiedener Anzeigemodi (welche von der FlowDocumentReaderViewingMode-Enumeration bereitgestellt werden). Dies ist jedoch ressourcenintensiver als FlowDocumentPageViewer oder FlowDocumentScrollViewer.

Standardmäßig wird immer eine vertikale Bildlaufleiste und eine horizontale Bildlaufleiste nach Bedarf angezeigt. Die Standardbenutzeroberfläche für FlowDocumentScrollViewer enthält keine Symbolleiste; die IsToolBarVisible-Eigenschaft kann jedoch verwendet werden, um eine integrierte Symbolleiste zu aktivieren.

RichTextBox

Mit einer RichTextBox können Sie es dem Benutzer ermöglichen, fortlaufenden Inhalt zu bearbeiten. Wenn Sie beispielsweise einen Editor erstellen möchten, der einem Benutzer ermöglicht, Elemente wie Tabellen, kursive und fette Formatierung usw. zu ändern, verwenden Sie eine RichTextBox. Weitere Informationen finden Sie unter Übersicht über RichTextBox.

Hinweis: Fortlaufender Inhalt in einer RichTextBox verhält sich nicht genau wie in anderen Steuerelementen enthaltener fortlaufender Inhalt. Zum Beispiel gibt es in einer RichTextBox keine Spalten und somit auch keine automatische Größenanpassung. Auch die typischen integrierten Features von fortlaufendem Inhalt wie die Suchfunktion, der Anzeigemodus, die Seitennavigation und die Zoomfunktion stehen in einer RichTextBox nicht zur Verfügung.

Erstellen von fortlaufendem Inhalt

Fortlaufender Inhalt kann komplex sein und aus verschiedenen Elementen bestehen, darunter Text, Bilder, Tabellen und sogar Klassen, die von UIElement abgeleitet sind, wie z. B. Steuerelemente. Um zu verstehen, wie komplexer fortlaufender Inhalt erstellt wird, sind die folgenden Punkte wichtig:

  • Flussbezogene Klassen: Jede im fortlaufenden Inhalt verwendete Klasse hat einen bestimmten Zweck. Außerdem hilft die hierarchische Beziehung zwischen flussbezogenen Klassen Ihnen, zu verstehen, wie diese Klassen verwendet werden. Beispielsweise werden Klassen, die von der Block-Klasse abgeleitet werden, zur Speicherung anderer Objekte verwendet, während von Inline abgeleitete Klassen Objekte enthalten, die angezeigt werden.

  • Inhaltsschema: Ein Flussdokument kann eine beträchtliche Anzahl von geschachtelten Elementen erfordern. Das Inhaltsschema gibt mögliche Beziehungen zwischen übergeordneten und untergeordneten Elementen an.

In den folgenden Abschnitten wird jeder dieser Bereiche ausführlicher behandelt.

Flussbezogene Klassen

Das Diagramm unten zeigt die für fortlaufenden Inhalt am häufigsten verwendeten Objekte:

Diagramm: Flussinhaltselement-Klassenhierarchie

Für den fortlaufenden Inhalt gibt es zwei wichtige Kategorien:

  1. Von Block abgeleitete Klassen: Auch "Blockinhaltselemente" oder einfach "Blockelemente" genannt. Mit Elementen, die von Block erben, können Elemente unter einem gemeinsamen übergeordneten Element gruppiert oder gemeinsame Attribute auf eine Gruppe angewendet werden.

  2. Von Inline abgeleitete Klassen: Werden auch "Inlineinhaltselemente" oder einfach "Inlineelemente" genannt. Elemente, die von Inline erben, sind entweder in einem Blockelement oder einem anderen Inlineelement enthalten. Inlineelemente werden oft als direkter Container für Inhalt verwendet, der auf den Bildschirm gerendert wird. Beispielsweise kann ein Paragraph (Blockelement) ein Run (Inlineelement) enthalten, aber Run enthält den Text, der auf dem Bildschirm gerendert wird.

Jede Klasse in diesen zwei Kategorien wird unten kurz beschrieben.

Von Block abgeleitete Klassen

Paragraph

Paragraph wird in der Regel verwendet, um Inhalt in einen Absatz zu gruppieren. Die einfachste und häufigste Verwendung von Paragraph ist, einen Absatz mit Text zu erstellen.

<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://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;
        }
    }
}

Aber Sie können auch andere von Inline abgeleitete Elemente verwenden. Dies wird unten erläutert.

Section

Section wird nur verwendet, um andere von Block abgeleitete Elemente zu speichern. Section wendet keine Standardformatierung auf die Elemente an, die es enthält. Alle für Section festgelegten Eigenschaftenwerte gelten jedoch für seine untergeordneten Elemente. Ein Abschnitt ermöglicht Ihnen auch, seine untergeordnete Auflistung programmgesteuert zu durchlaufen. Section wird ähnlich verwendet wie das <DIV>-Tag in HTML.

Im Beispiel unten werden drei Absätze unter einem Section definiert. Der Abschnitt hat den Background-Eigenschaftenwert Red, dementsprechend ist die Hintergrundfarbe für die Absätze ebenfalls Rot.

<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://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;
        }
    }
}

BlockUIContainer

Mit BlockUIContainer können UIElement-Elemente (z. B. Button) in von Block abgeleiteten fortlaufenden Inhalt eingebettet werden. InlineUIContainer (siehe unten) wird verwendet, um UIElement-Elemente in von Inline abgeleiteten fortlaufenden Inhalt einzubetten. BlockUIContainer und InlineUIContainer sind wichtig, da es keine andere Möglichkeit gibt, ein UIElement in fortlaufendem Inhalt zu verwenden, wenn es nicht in einem dieser zwei Elemente enthalten ist.

Das folgende Beispiel zeigt, wie das BlockUIContainer-Element verwendet wird, um UIElement-Objekte im fortlaufenden Inhalt zu hosten.

<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>

In der folgenden Abbildung wird gezeigt, wie dieses Beispiel gerendert wird.

Bildschirmabbildung: UIElement eingebettet in fortlaufenden Inhalt

List

List wird verwendet, um eine Aufzählung mit Aufzählungszeichen oder Zahlen zu erstellen. Legen Sie für die MarkerStyle-Eigenschaft einen TextMarkerStyle-Enumerationswert fest, um den Stil der Liste festzulegen. Im Beispiel unten wird das Erstellen einer einfachen Liste veranschaulicht.

<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://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;
        }
    }
}

Hinweis:List ist das einzige Fließelement, das die ListItemCollection verwendet, um untergeordnete Elemente zu verwalten.

Table

Table wird zum Erstellen einer Tabelle verwendet. Table ähnelt dem Grid-Element, besitzt aber mehr Fähigkeiten und erfordert deshalb mehr Ressourcen. Da Grid ein UIElement ist, kann es nicht in fortlaufendem Inhalt verwendet werden, es sei denn, es ist in einem BlockUIContainer oder InlineUIContainer enthalten. Weitere Informationen zu Table finden Sie unter Übersicht über Tabellen.

Von Inline abgeleitete Klassen

Run

Run wird zur Speicherung von unformatiertem Text verwendet. Man würde erwarten, dass Run-Objekte in fortlaufendem Inhalt häufig verwendet werden, jedoch müssen Run-Elemente im Markup nicht explizit verwendet werden. So gibt im Markup unten der erste Paragraph das Run-Element explizit an, der zweite hingegen nicht. Für beide Absätze ist die Ausgabe gleich.

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

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

Hinweis:Run muss verwendet werden, wenn Flussdokumente mithilfe von Code erstellt oder bearbeitet werden.

Span

Span fasst andere Inlineinhaltselemente in einer Gruppe zusammen. Inhalt in einem Span-Element wird nicht inhärent gerendert. Elemente, die von Span erben, darunter Hyperlink, Bold, Italic und Underline, formatieren jedoch den Text.

Unten finden Sie ein Beispiel, in dem Span verwendet wird, um Inlineinhalt einschließlich Text, Bold-Element und Button zu speichern.

<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://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>

Die folgende Bildschirmabbildung zeigt, wie dieses Beispiel gerendert wird.

Bildschirmabbildung: Gerendertes SPAN-Beispiel

InlineUIContainer

Mit InlineUIContainer können UIElement-Elemente (beispielsweise ein Steuerelement wie Button) in ein Inline-Inhaltselement eingebettet werden. Dieses Element ist die Inlineentsprechung zu dem oben beschriebenen BlockUIContainer. Unten finden Sie ein Beispiel, in dem InlineUIContainer verwendet wird, um ein Button-Element inline in einen Paragraph einzufügen.

<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://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;
        }
    }
}

Hinweis:InlineUIContainer muss nicht explizit in Markup verwendet werden. Wenn Sie ihn weglassen, wird in jedem Fall ein InlineUIContainer erstellt, wenn der Code kompiliert wird.

Figure und Floater

Figure und Floater werden verwendet, um Inhalt in Flussdokumenten mit Placement-Eigenschaften einzubetten, die unabhängig vom fortlaufenden Hauptinhalt angepasst werden können. Figure-Elemente oder Floater-Elemente werden häufig verwendet, um Teile des Inhalts zu markieren oder hervorzuheben, um unterstützende Bilder oder anderen Inhalt im fortlaufenden Hauptinhalt zu hosten oder um lose verbundenen Inhalt einzufügen, z. B. Werbeanzeigen.

Das folgende Beispiel zeigt, wie eine Figure in einen Textabsatz eingebettet wird.

<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://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;
        }
    }
}

Die folgende Abbildung zeigt, wie dieses Beispiel gerendert wird:

Bildschirmabbildung: Abbildungsbeispiel

Figure und Floater unterscheiden sich in vielerlei Hinsicht und werden für verschiedene Szenarios verwendet.

Figure:

  • Kann positioniert werden: Sie können die horizontalen und vertikalen Anker festlegen und die Abbildung relativ zur Seite, zum Inhalt, zur Spalte oder zum Absatz andocken. Mit der HorizontalOffset-Eigenschaft und der VerticalOffset-Eigenschaft können Sie auch beliebige Offsets angeben.

  • Die Größe kann an mehrere Spalten angepasst werden: Sie können die Höhe und Breite der Figure auf das Vielfache von Seiten, des Inhalts oder der Spaltenhöhe oder -breite festlegen. Bei Seiten und Inhalt sind Vielfache größer als 1 nicht zulässig. Beispielsweise können Sie die Breite einer Figure auf eine halbe Seite, ein Viertel des Inhalts oder zwei Spalten festlegen ("0.5 page", "0.25 content", "2 Column"). Sie können die Höhe und Breite auch auf absolute Pixelwerte festlegen.

  • Keine Paginierung: Wenn der Inhalt einer Figure größer als die Figure ist, wird so viel Inhalt gerendert, wie eingefügt werden kann; der übrige Inhalt wird nicht angezeigt.

Floater:

  • Kann nicht positioniert werden und wird gerendert, wo entsprechend Platz verfügbar gemacht werden kann. Für einen Floater können Sie den Offset nicht festlegen und keine Verankerung angeben.

  • Die Größe kann nicht für mehrere Spalten angepasst werden: In der Standardeinstellung wird die Größe von Floater an eine Spalte angepasst. Der Floater verfügt über eine Width-Eigenschaft, die auf einen absoluten Pixelwert festgelegt werden kann. Wenn der Wert jedoch größer als die Breite einer Spalte ist, wird der Wert ignoriert und der Floater auf die Spaltenbreite festgelegt. Die Größe kann durch Festlegen der korrekten Pixelbreite so angepasst werden, dass sie kleiner als eine Spalte ist. Das Anpassen der Größe kann jedoch nicht relativ zur Spaltenbreite erfolgen, sodass "0.5Column" kein gültiger Ausdruck für die Floater-Breite ist. Eine Eigenschaft für die Höhe ist für den Floater nicht vorhanden, und seine Höhe kann nicht festgelegt werden. Diese hängt vielmehr vom Inhalt ab.

  • Floater werden paginiert: Wenn der Inhalt an der angegebenen Breite größer als 1 Spaltenhöhe ist, wird der Floater umbrochen und auf der nächsten Spalte, Seite usw. paginiert.

Eine Figure eignet sich gut zum Einfügen eigenständigen Inhalts, dessen Größe und Positionierung Sie steuern möchten und bei dem Sie sicher sind, dass er in das Element mit der vorgegebenen Größe passt. Ein Floater eignet sich gut zum Einfügen freien fortlaufenden Inhalts, der ähnlich wie der Inhalt der Hauptseite, aber getrennt von diesem verläuft.

LineBreak

LineBreak bewirkt, dass ein Zeilenumbruch in fortlaufendem Inhalt auftritt. Das folgende Beispiel veranschaulicht die Verwendung von LineBreak.

<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://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>

Die folgende Bildschirmabbildung zeigt, wie dieses Beispiel gerendert wird.

Bildschirmabbildung: LineBreak-Beispiel

Auflistung von fortlaufenden Inhaltselementen

In vielen der Beispiele oben werden BlockCollection und InlineCollection verwendet, um fortlaufenden Inhalt programmgesteuert zu erstellen. Um beispielsweise Elemente zu einem Paragraph hinzuzufügen, können Sie diese Syntax verwenden:

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

So wird Run zur InlineCollection des Paragraph hinzugefügt. Dies entspricht dem impliziten Run in einem Paragraph in Markup:

<Paragraph>

Some Text

</Paragraph>

Als Beispiel für die Verwendung der BlockCollection wird im folgenden Beispiel ein neuer Section erstellt und anschließend die Add-Methode verwendet, um einen neuen Paragraph zu den Section-Inhalten hinzuzufügen.

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

Sie können nicht nur Elemente zu einer Auflistung von fortlaufenden Inhaltselementen hinzufügen, sondern auch Elemente entfernen. Im folgenden Beispiel wird das letzte Inline-Element in Span gelöscht.

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

Im folgenden Beispiel wird der gesamte Inhalt (Inline-Elemente) aus Span gelöscht.

spanx.Inlines.Clear();

Wenn Sie programmgesteuert mit fortlaufendem Inhalt arbeiten, werden Sie diese Auflistungen wahrscheinlich häufig verwenden.

Ob ein Fließelement eine InlineCollection (Inlines) oder eine BlockCollection (Blöcke) zur Speicherung der untergeordneten Elemente verwendet, hängt davon ab, welche Typen von untergeordneten Elementen (Block oder Inline) in dem übergeordneten Element enthalten sein können. Kapselungsregeln für fortlaufende Inhaltselemente werden im Inhaltsschema im nächsten Abschnitt zusammengefasst.

Hinweis: Es gibt einen dritten Auflistungstyp, der mit Fließinhalt verwendet wird, nämlich die ListItemCollection. Diese Auflistung wird aber nur mit einer List verwendet. Außerdem gibt es mehrere mit Table verwendete Auflistungen. Weitere Informationen finden Sie unter Übersicht über Tabellen.

Inhaltsschema

Angesichts der Anzahl von verschiedenen fortlaufenden Inhaltselementen kann es schwierig sein, nachzuverfolgen, welche Arten von untergeordneten Elementen in einem Element gespeichert werden können. Das Diagramm unten fasst die Kapselungsregeln für Fließelemente zusammen. Die Pfeile stellen die möglichen Beziehungen zwischen übergeordneten und untergeordneten Elementen dar.

Diagramm: Flussinhalt-Kapselungsschema

Wie aus dem Diagramm oben ersichtlich, hängen die für ein Element zulässigen untergeordneten Elemente nicht unbedingt davon ab, ob es sich um ein Block-Element oder ein Inline-Element handelt. Beispielsweise kann Span (ein Inline-Element) nur Inline-Elemente als untergeordnete Elemente haben, während Figure (ebenfalls ein Inline-Element) nur Block-Elemente als untergeordnete Elemente haben kann. Aus diesem Grund ist ein Diagramm nützlich, um schnell zu bestimmen, welches Element in einem anderen enthalten sein kann. Als Beispiel kann das Diagramm verwendet werden, um festzustellen, wie der Fließinhalt einer RichTextBox konstruiert werden kann.

1. Eine RichTextBox muss ein FlowDocument enthalten, das wiederum ein von einem Block abgeleitetes Objekt enthalten muss. Unten finden Sie das entsprechende Segment aus dem Diagramm oben.

Diagramm: RichTextBox-Kapselungsregeln

So könnte das Markup zu diesem Zeitpunkt aussehen.

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

2. Gemäß dem Diagramm können Sie zwischen mehreren Block-Elementen wählen, darunter Paragraph, Section, Table, List und BlockUIContainer (siehe Von Block abgeleitete Klassen weiter oben). Angenommen, das gewünschte Element ist eine Table. Gemäß dem Diagramm oben enthält eine Table eine TableRowGroup, in der TableRow-Elemente enthalten sind, die TableCell-Elemente enthalten, welche ein von einem Block abgeleitetes Objekt enthalten. Unten befindet sich das entsprechende Segment für Table, das aus dem Diagramm oben entnommen wurde.

Diagramm: Übergeordnetes/Untergeordnetes Schema für Tabelle

Unten finden Sie das entsprechende Markup.

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

  </FlowDocument>
</RichTextBox>

3. Wiederum sind ein oder mehrere Block-Elemente unter einer TableCell erforderlich. Um bei einem einfachen Beispiel zu bleiben, platzieren Sie einen kurzen Text in der Zelle. Dazu können Sie einen Paragraph mit einem Run-Element verwenden. Unten finden Sie die entsprechenden Segmente aus dem Diagramm, die zeigen, dass ein Paragraph ein Inline-Element und Run (ein Inline-Element) lediglich Nur-Text enthalten kann.

Diagramm: Übergeordnetes/Untergeordnetes Schema für AbsatzDiagramm: Übergeordnetes/Untergeordnetes Schema für Ausführung

Unten sehen Sie das ganze Beispiel in Markup.

<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://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>

Anpassen von Text

Normalerweise ist Text der vorherrschende Inhaltstyp in einem Fließdokument. Obwohl die oben eingeführten Objekte verwendet werden können, um die meisten Möglichkeiten für das Rendern von Text zu steuern, gibt es einige andere Methoden zum Anpassen von Text, die in diesem Abschnitt erläutert werden.

Textdekorationen

Mit Textdekorationen können Sie die Effekte Unterstreichen, Überstreichen, Baseline und Durchstreichen auf Text anwenden (siehe Abbildungen unten). Diese Dekorationen werden mithilfe der TextDecorations-Eigenschaft hinzugefügt, die von mehreren Objekten verfügbar gemacht wird, darunter Inline, Paragraph, TextBlock und TextBox.

Im folgenden Beispiel wird das Festlegen der TextDecorations-Eigenschaft von einem Paragraph veranschaulicht.

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

In der folgenden Abbildung wird gezeigt, wie dieses Beispiel gerendert wird.

Bildschirmabbildung: Text mit standardmäßigem Durchstreicheffekt

In den folgenden Abbildungen wird veranschaulicht, wie die Dekorationen Überstreichen, Baseline und Unterstreichen gerendert werden.

Bildschirmabbildung: Überstrich-TextDecoratorBildschirmabbildung: Standardmäßiger Baseline-Effekt auf TextBildschirmabbildung: Text mit standardmäßigem Unterstreichungseffekt

Typografie

Die Typography-Eigenschaft wird von den meisten flussbezogenen Inhalten verfügbar gemacht, darunter TextElement, FlowDocument, TextBlock und TextBox. Diese Eigenschaft wird verwendet, um typografische Eigenschaften/Variationen von Text (z. B. Kapitälchen oder Großbuchstaben, hochgestellten und tiefgestellten Text usw.) zu steuern.

Im folgenden Beispiel wird anhand des Beispiels Paragraph veranschaulicht, wie das Typography-Attribut festgelegt wird.

<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>

In der folgenden Abbildung wird das Rendering dieses Beispiels veranschaulicht.

Bildschirmabbildung: Text mit geänderter Typografie

Im Gegensatz dazu wird in der folgenden Abbildung gezeigt, wie ein ähnliches Beispiel mit den Standardtypografieeigenschaften gerendert wird.

Bildschirmabbildung: Text mit geänderter Typografie

Im folgenden Beispiel wird veranschaulicht, wie die Typography-Eigenschaft programmgesteuert festgelegt wird.

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;

Weitere Informationen über Typografie finden Sie unter Typografie in Windows Presentation Foundation.

Siehe auch

Aufgaben

Demo für SDK Viewer

Konzepte

Optimieren der Leistung: Text

Typografie in Windows Presentation Foundation

Übersicht über das TextElement-Inhaltsmodell

Übersicht über RichTextBox

Dokumente in Windows Presentation Foundation

Übersicht über Tabellen

Übersicht über Anmerkungen

Weitere Ressourcen

Beispiele für fortlaufende Inhaltselemente

Gewusst-wie-Themen zu fortlaufenden Inhaltselementen