Dela via


Översikt över flödesdokument

Flödesdokument är utformade för att optimera visning och läsbarhet. Istället för att vara inställda på en fördefinierad layout, anpassar flödande dokument dynamiskt sitt innehåll baserat på körningsvariabler som fönsterstorlek, enhetsupplösning och valfria användarinställningar. Dessutom erbjuder flödesdokument avancerade dokumentfunktioner, till exempel sidnumrering och kolumner. Det här avsnittet innehåller en översikt över flödesdokument och hur du skapar dem.

Vad är ett flödesdokument

Ett flödesdokument är utformat för att "omsätta innehåll" beroende på fönsterstorlek, enhetsupplösning och andra miljövariabler. Dessutom har flödesdokument ett antal inbyggda funktioner som sökning, visningslägen som optimerar läsbarheten och möjligheten att ändra teckensnittens storlek och utseende. Flödesdokument används bäst när enkel läsning är det primära scenariot för dokumentförbrukning. Däremot är fasta dokument utformade för att ha en statisk presentation. Fasta dokument är användbara när det är viktigt att källinnehållet återges med noggrannhet. Mer information om olika typer av dokument finns i Dokument i WPF.

Följande bild visar ett exempelflödesdokument som visas i flera fönster med olika storlekar. När visningsområdet ändras flödar innehållet om så att det tillgängliga utrymmet används på bästa sätt.

flödesdokumentinnehållsflöde

Som du ser i bilden ovan kan flödesinnehållet innehålla många komponenter, inklusive stycken, listor, bilder med mera. Dessa komponenter motsvarar element i markering och objekt i procedurkod. Vi går över dessa klasser i detalj senare i avsnittet Flow Related Classes i den här översikten. För tillfället är här ett enkelt kodexempel som skapar ett flödesdokument som består av ett stycke med fet text och en lista.

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

Bilden nedan visar hur det här kodfragmentet ser ut.

Skärmbild: Renderat FlowDocument-exempel

I det här exemplet används FlowDocumentReader-kontrollen som värd för flödesinnehållet. För mer information om kontroller för flödesinnehåll, se Flödesdokumenttyper. Paragraph, List, ListItemoch Bold element används för att styra innehållsformatering baserat på deras ordning i markering. Det Bold elementet sträcker sig till exempel bara över en del av texten i stycket. Därför är endast den delen av texten fet. Om du har använt HTML är detta bekant för dig.

Som du ser i bilden ovan finns det flera inbyggda funktioner i Flödesdokument:

  • Sök: Gör att användaren kan utföra en fullständig textsökning av ett helt dokument.

  • Visningsläge: Användaren kan välja önskat visningsläge, inklusive ett visningsläge för en sida (sida i taget), ett visningsläge med två sidor i taget (bokläsningsformat) och ett kontinuerligt rullningsläge (bottenlöst). Mer information om dessa visningslägen finns i FlowDocumentReaderViewingMode.

  • Sidnavigeringskontroller: Om visningsläget för dokumentet använder sidor innehåller sidnavigeringskontrollerna en knapp för att hoppa till nästa sida (nedåtpilen) eller föregående sida (uppåtpilen), samt indikatorer för det aktuella sidnumret och det totala antalet sidor. Att bläddra igenom sidor kan också utföras med hjälp av piltangenterna.

  • Zooma: Zoomkontrollerna gör det möjligt för användaren att öka eller minska zoomnivån genom att klicka på plus- respektive minusknapparna. Zoomkontrollerna innehåller också ett skjutreglage för att justera zoomnivån. Mer information finns i Zoom.

Dessa funktioner kan ändras baserat på den kontroll som används för att vara värd för flödesinnehållet. I nästa avsnitt beskrivs de olika kontrollerna.

Flödesdokumenttyper

Visning av flödesdokumentinnehåll och hur det visas beror på vilket objekt som används som värd för flödesinnehållet. Det finns fyra kontroller som stöder visning av flödesinnehåll: FlowDocumentReader, FlowDocumentPageViewer, RichTextBoxoch FlowDocumentScrollViewer. Dessa kontroller beskrivs kortfattat nedan.

Anmärkning

FlowDocument krävs för att direkt kunna vara värd för flödesinnehåll, så alla dessa visningskontroller använder en FlowDocument för att möjliggöra flödesinnehållshantering.

Flowdokumentläsare

FlowDocumentReader innehåller funktioner som gör det möjligt för användaren att dynamiskt välja mellan olika visningslägen, inklusive ett visningsläge med en sida (sida i taget), ett visningsläge med två sidor i taget (bokläsningsformat) och ett kontinuerligt rullningsläge (bottenlöst). Mer information om dessa visningslägen finns i FlowDocumentReaderViewingMode. Om du inte behöver möjligheten att dynamiskt växla mellan olika visningslägen, tillhandahåller FlowDocumentPageViewer och FlowDocumentScrollViewer lättare innehållsvisare som är fasta i ett visst visningsläge.

FlowDocumentPageViewer och FlowDocumentScrollViewer

FlowDocumentPageViewer visar innehåll i visningsläge sida vid sida, medan FlowDocumentScrollViewer visar innehåll i kontinuerligt rullningsläge. Både FlowDocumentPageViewer och FlowDocumentScrollViewer är fasta i ett visst visningsläge. Jämför med FlowDocumentReader, som innehåller funktioner som gör det möjligt för användaren att dynamiskt välja mellan olika visningslägen (enligt FlowDocumentReaderViewingMode uppräkning), på bekostnad av att vara mer resursintensiv än FlowDocumentPageViewer eller FlowDocumentScrollViewer.

Som standard visas alltid en lodrät rullningslist och en vågrät rullningslist visas om det behövs. Standardgränssnittet för FlowDocumentScrollViewer innehåller inte något verktygsfält. Egenskapen IsToolBarVisible kan dock användas för att aktivera ett inbyggt verktygsfält.

RikTextBox

Du använder en RichTextBox när du vill tillåta att användaren redigerar flödesinnehåll. Om du till exempel vill skapa en redigerare som gör det möjligt för en användare att ändra saker som tabeller, kursiv och fet formatering osv, skulle du använda en RichTextBox. Mer information finns i Översikt över RichTextBox.

Anmärkning

Flödesinnehåll i en RichTextBox fungerar inte exakt som flödesinnehållet i andra kontroller. Det finns till exempel inga kolumner i en RichTextBox och därmed inget automatiskt storleksändringsbeteende. Dessutom är de vanligtvis inbyggda funktionerna i flödesinnehåll som sökning, visningsläge, sidnavigering och zoom inte tillgängliga inom en RichTextBox.

Skapa flödesinnehåll

Flödesinnehåll kan vara komplext och består av olika element, till exempel text, bilder, tabeller och till och med UIElement härledda klasser som kontroller. Följande punkter är viktiga för att förstå hur du skapar komplext flödesinnehåll:

  • Flow-relaterade klasser: Varje klass som används i flödesinnehåll har ett specifikt syfte. Dessutom hjälper den hierarkiska relationen mellan flödesklasser dig att förstå hur de används. Klasser som härleds från klassen Block används till exempel för att innehålla andra objekt medan klasser som härleds från Inline innehåller objekt som visas.

  • innehållsschema: Ett flödesdokument kan kräva ett stort antal kapslade element. Innehållsschemat anger möjliga överordnade/underordnade relationer mellan element.

Följande avsnitt går igenom vart och ett av dessa områden mer detaljerat.

Diagrammet nedan visar de objekt som oftast används med flödesinnehåll:

Diagram: Flödesinnehållselementklasshierarki

För flödesinnehåll finns det två viktiga kategorier:

  1. Block-härledda klasser: Kallas också (blockinnehållselement) eller bara (blockelement). Element som ärver från Block kan användas för att gruppera element under en gemensam överordnad eller för att tillämpa vanliga attribut på en grupp.

  2. Inline-härledda klasser: Kallas även "Inline-innehållselement" eller bara "Inline-element". Element som ärver från Inline finns antingen i ett blockelement eller ett annat infogat element. Infogade element används ofta som direktcontainer med innehåll som återges på skärmen. Till exempel kan en Paragraph (blockelement) innehålla en Run (infogat element) men Run innehåller faktiskt texten som återges på skärmen.

Varje klass i dessa två kategorier beskrivs kortfattat nedan.

Blockbaserade klasser

stycke

Paragraph används vanligtvis för att gruppera innehåll i ett stycke. Den enklaste och vanligaste användningen av Stycke är att skapa ett stycke text.

<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

Men du kan också inkludera andra infogade element som du kommer att se nedan.

Avsnitt

Section används endast för att innehålla andra Block-härledda element. Den tillämpar inte någon standardformatering på de element som den innehåller. Alla egenskapsvärden som anges på en Section gäller dock för dess underordnade element. Med ett avsnitt kan du också iterera programmatiskt genom dess underliggande samling. Section används på ett liknande sätt som taggen <DIV> i HTML.

I exemplet nedan definieras tre stycken under en Section. Avsnittet har ett Background egenskapsvärde för Röd, och därför är bakgrundsfärgen för styckena också röd.

<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 gör att UIElement element (dvs. en Button) kan bäddas in i blockbaserat flödesinnehåll. InlineUIContainer (se nedan) används för att bädda in UIElement element i infogat flödesinnehåll. BlockUIContainer och InlineUIContainer är viktiga eftersom det inte finns något annat sätt att använda en UIElement i flödesinnehåll om det inte finns i något av dessa två element.

I följande exempel visas hur du använder elementet BlockUIContainer som värd för UIElement objekt i flödesinnehållet.

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

Följande bild visar hur det här exemplet återges:

Skärmbild som visar ett UIElement inbäddat i flödesinnehåll.

Lista

List används för att skapa en punktlista eller numerisk lista. Ange egenskapen MarkerStyle till ett TextMarkerStyle uppräkningsvärde för att fastställa listans formatmall. Exemplet nedan visar hur du skapar en enkel lista.

<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

Anmärkning

List är det enda flödeselementet som använder ListItemCollection för att hantera underordnade element.

Tabell

Table används för att skapa en tabell. Table liknar elementet Grid men har fler funktioner och kräver därför större resurskostnader. Eftersom Grid är en UIElementkan det inte användas i flödesinnehåll såvida det inte är inneslutet i en BlockUIContainer eller InlineUIContainer. Mer information om Tablefinns i Tabellöversikt.

Inlinjehärledda klasser

Springa

Run används för att innehålla oformaterad text. Du kan förvänta dig att Run objekt används i stor utsträckning i flödesinnehåll. I markering krävs dock inte att Run-element används uttryckligen. Run måste användas när du skapar eller manipulerar flödesdokument med hjälp av kod. I markeringen nedan anger den första Paragraph uttryckligen Run-elementet medan det andra inte uttrycker det. Båda styckena genererar identiska utdata.

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

Anmärkning

Från och med .NET Framework 4 är egenskapen Text för objektet Run en beroendeegenskap. Du kan binda egenskapen Text till en datakälla, till exempel en TextBlock. Egenskapen Text stöder helt enkelriktad bindning. Egenskapen Text stöder också tvåvägsbindning, förutom RichTextBox. Ett exempel finns i Run.Text.

Spann

Span grupperar andra infogade innehållselement. Ingen inbyggd rendering tillämpas på innehåll i ett Span element. Element som ärver från Span inklusive Hyperlink, Bold, Italic och Underline använder formatering på text.

Nedan visas ett exempel på en Span som används för att innehålla infogat innehåll, inklusive text, ett Bold-element och en 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>

Följande skärmbild visar hur det här exemplet återges.

Skärmbild: Exempel på renderat intervall

InlineUIContainer

InlineUIContainer gör att UIElement element (t.ex. en kontroll som Button) kan bäddas in i ett Inline innehållselement. Det här elementet är den infogade motsvarigheten till BlockUIContainer som beskrivs ovan. Nedan visas ett exempel som använder InlineUIContainer för att infoga en Button i en 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

Anmärkning

InlineUIContainer behöver inte användas explicit i markering. Om du utelämnar det skapas en InlineUIContainer ändå när koden kompileras.

Figur och Floater

Figure och Floater används för att bädda in innehåll i Flödesdokument med placeringsegenskaper som kan anpassas oberoende av det primära innehållsflödet. Figure eller Floater element används ofta för att markera eller accentuera delar av innehåll, för att vara värd för stödjande bilder eller annat innehåll i huvudinnehållsflödet eller för att mata in löst relaterat innehåll, till exempel annonser.

I följande exempel visas hur du bäddar in en Figure i ett textstycke.

<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

Följande bild visar hur det här exemplet återges.

Skärmbild: Bildexempel

Figure och Floater skiljer sig åt på flera sätt och används för olika scenarier.

Bild:

  • Kan placeras: Du kan ange dess vågräta och lodräta fästpunkter för att docka den i förhållande till sidan, innehållet, kolumnen eller stycket. Du kan också använda egenskaperna HorizontalOffset och VerticalOffset för att ange godtyckliga förskjutningar.

  • Kan vara större än en kolumn: Du kan ange Figure höjd och bredd till multiplar av sid-, innehålls- eller kolumnhöjd eller bredd. Observera att multiplar som är större än 1 inte tillåts när det gäller sida och innehåll. Du kan till exempel ange bredden på en Figure till "0,5-sida" eller "0,25-innehåll" eller "2 kolumn". Du kan också ange höjd och bredd till absoluta pixelvärden.

  • Paginerar inte: Om innehållet i en Figure inte får plats i Figure, återges det innehåll som passar och det återstående innehållet går förlorat.

Flytande:

  • Kan inte placeras och kommer att visas där det finns plats för det. Du kan inte ange förskjutningen eller fästpunkten för en Floater.

  • Det går inte att ändra storleken till mer än en kolumn: Som standard justeras Floater till en kolumn. Den har en Width egenskap som kan anges till ett absolut pixelvärde, men om det här värdet är större än en kolumnbredd ignoreras den och floatern är storleksanpassad på en kolumn. Du kan ändra storleken till mindre än en kolumn genom att ange rätt pixelbredd, men storleken är inte kolumnrelativ, så "0.5Column" är inte ett giltigt uttryck för Floater bredd. Floater har ingen höjdegenskap och dess höjd kan inte justeras; dess höjd beror på innehållet.

  • Floater paginates: Om innehållet vid den angivna bredden sträcker sig till mer än 1 kolumnhöjd, bryts objektet upp och flyttas till nästa kolumn, nästa sida och så vidare.

Figure är ett bra ställe att placera fristående innehåll där du vill styra storlek och placering och är säker på att innehållet får plats i den angivna storleken. Floater är ett bra ställe att placera mer fritt flödande innehåll som flödar ungefär som huvudsidans innehåll, men som är skilt från det.

Radbrytning

LineBreak orsakar en radbrytning i flödesinnehållet. I följande exempel visas användningen av 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>

Följande skärmbild visar hur det här exemplet återges.

Skärmbild: LineBreak-exempel

Flödessamlingselement

I många av exemplen ovan används BlockCollection och InlineCollection för att konstruera flödesinnehåll programmatiskt. Om du till exempel vill lägga till element i en Paragraphkan du använda syntaxen:

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

Detta lägger till en Run i InlineCollection för Paragraph. Det här är samma som den implicita Run som finns i en Paragraph i ett markup-språk.

<Paragraph>
Some Text
</Paragraph>

Som ett exempel på hur du använder BlockCollectionskapar följande exempel en ny Section och använder sedan metoden Lägg till för att lägga till en ny Paragraph i innehållet i 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...")))

Förutom att lägga till objekt i en flödessamling kan du även ta bort objekt. I följande exempel tas det sista Inline elementet bort i Span.

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

I följande exempel rensas allt innehåll (Inline element) från Span.

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

När du arbetar med flödesinnehåll programmatiskt använder du förmodligen dessa samlingar i stor utsträckning.

Om ett flödeselement använder InlineCollection (infogade objekt) eller BlockCollection (block) för att bestå av sina underordnade element beror på vilken typ av underordnade element (Block eller Inline) som kan ingå i det överordnade elementet. Inneslutningsregler för flödesinnehållselement sammanfattas i innehållsschemat i nästa avsnitt.

Anmärkning

Det finns en tredje typ av samling som används med flödesinnehåll, ListItemCollection, men den här samlingen används endast med en List. Dessutom finns det flera samlingar som används med Table. Mer information finns i Tabellöversikt.

Innehållsschema

Med det stora antalet olika flödesinnehållselement kan det vara överväldigande att hålla reda på vilken typ av del- eller underordnade element ett specifikt element kan innehålla. Diagrammet nedan sammanfattar inneslutningsreglerna för flödeselement. Pilarna representerar möjliga föräldra-barnrelationer.

Diagram: Flödesinnehållsschema

Som framgår av diagrammet ovan, bestäms inte nödvändigtvis vilka underordnade element som tillåts för ett element av om det är ett Block-element eller ett Inline-element. Till exempel kan en Span (ett Inline-element) bara ha Inline underordnade element medan en Figure (även ett Inline-element) bara kan ha Block underordnade element. Därför är ett diagram användbart för att snabbt avgöra vilket element som kan ingå i ett annat. Vi använder till exempel diagrammet för att fastställa hur flödesinnehållet i en RichTextBoxska konstrueras.

1. A RichTextBox måste innehålla en FlowDocument som i sin tur måste innehålla ett Block-härlett objekt. Nedan visas motsvarande segment från diagrammet ovan.

Diagram: RichTextBox-inneslutningsregler

Hittills kan markeringen se ut så här.

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

2. Enligt diagrammet finns det flera Block element att välja mellan, inklusive Paragraph, Section, Table, Listoch BlockUIContainer (se Block-härledda klasser ovan). Låt oss säga att vi vill ha en Table. Enligt diagrammet ovan innehåller en Table en TableRowGroup som innehåller TableRow element, som innehåller TableCell element som innehåller ett Block-härlett objekt. Nedan visas motsvarande segment för Table som hämtats från diagrammet ovan.

diagram: Överordnat/underordnat schema för tabell

Nedan visas motsvarande markering.

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

3. Igen krävs ett eller flera Block element under en TableCell. För att göra det enkelt ska vi placera lite text i cellen. Vi kan göra detta med hjälp av en Paragraph med ett Run-element. Nedan visas motsvarande segment från diagrammet som visar att en Paragraph kan ta ett Inline-element och att en Run (ett Inline-element) bara kan ta oformaterad text.

diagram: Överordnat/underordnat schema för stycke

Diagram: Föräldra/Barn-schema för Kör

Nedan visas hela exemplet i markupspråk.

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

Anpassning av text

Vanligtvis är text den vanligaste typen av innehåll i ett flödesdokument. Även om de objekt som introduceras ovan kan användas för att styra de flesta aspekter av hur text återges, finns det några andra metoder för att anpassa text som beskrivs i det här avsnittet.

Textdekorationer

Med textdekorationer kan du använda effekterna understrykning, överstreck, baslinje och genomstrykning på text (se bilder nedan). De här dekorationerna läggs till med egenskapen TextDecorations som exponeras av ett antal objekt, inklusive Inline, Paragraph, TextBlockoch TextBox.

I följande exempel visas hur du anger egenskapen TextDecorations för en Paragraph.

<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

Följande bild visar hur det här exemplet återges.

Skärmbild: Text med standardgenomstrykningseffekt

Följande siffror visar hur Overline, Baselineoch Understrykning dekorationer återges.

Skärmbild: Overline TextDecorator

Skärmbild: Standardbaslinjeeffekt på text

Skärmbild: Text med standardeffekt för understrykning

Typografi

Egenskapen Typography exponeras av det mesta flödesrelaterat innehåll, inklusive TextElement, FlowDocument, TextBlockoch TextBox. Den här egenskapen används för att styra typografiska egenskaper/varianter av text (t.ex. små eller stora versaler, göra upphöjda och nedsänkta bokstäver osv.).

I följande exempel visas hur du anger attributet Typography med Paragraph som exempelelement.

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

Följande bild visar hur det här exemplet återges.

Skärmbild som visar text med ändrad typografi.

Följande bild visar däremot hur ett liknande exempel med standardtypografiska egenskaper återges.

Skärmbild som visar text med standardtypografi.

I följande exempel visas hur du ställer in Typography-egenskapen programmatiskt.

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

Se typografi i WPF för mer information om typografi.

Se även