Vue d’ensemble des documents dynamiques

Les documents dynamiques sont conçus pour optimiser l’affichage et la lisibilité. Au lieu d’avoir une disposition prédéfinie, ces documents dynamiques ajustent et refluent dynamiquement leur contenu en fonction des variables d’exécution telles que la taille de la fenêtre, la résolution de l’appareil et les préférences facultatives de l’utilisateur. En outre, les documents dynamiques offrent des fonctionnalités de document avancées, telles que la pagination et les colonnes. Cette rubrique fournit une vue d’ensemble des documents dynamiques et explique comment les créer.

Description d’un document dynamique

Un document dynamique est conçu pour « redisposer le contenu » en fonction de la taille de la fenêtre, de la résolution de l’appareil et d’autres variables d’environnement. En outre, les documents dynamiques possèdent plusieurs fonctionnalités intégrées, notamment la recherche, les modes d’affichage qui optimisent la lisibilité et la possibilité de changer la taille et l’apparence des polices. Les documents dynamiques sont utilisés surtout quand la facilité de lecture est le scénario principal de consommation des documents. À l’inverse, les documents fixes sont conçus pour avoir une présentation statique. Ces documents sont utiles quand le contenu source doit être fidèlement respecté. Pour plus d’informations sur les différents types de documents, consultez Documents dans WPF.

L’illustration suivante montre un exemple de document dynamique affiché dans des fenêtres de différentes tailles. Chaque fois que la zone d’affichage change, le contenu est redisposé pour utiliser de façon optimale l’espace disponible.

Flow Document Content Reflow

Comme illustré dans l’image ci-dessus, le contenu dynamique peut comprendre plusieurs composants, notamment des paragraphes, des listes, des images et bien plus encore. Ces composants correspondent à des éléments dans le balisage et à des objets dans le code procédural. Nous étudierons ces classes en détail plus loin dans la section Classes liées au contenu dynamique de ce document. Pour le moment, voici un exemple de code simple qui crée un document dynamique comprenant un paragraphe avec du texte en gras et une liste.

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

Cet extrait de code est illustré ci-dessous.

Screenshot: Rendered FlowDocument example

Dans cet exemple, le FlowDocumentReader contrôle est utilisé pour héberger le contenu du flux. Pour plus d’informations sur les contrôles servant à héberger le contenu dynamique, consultez la section Types de documents dynamiques. Paragraph, , ListListItemet Bold les éléments sont utilisés pour contrôler la mise en forme du contenu, en fonction de leur ordre dans le balisage. Par exemple, l’élément Bold s’étend uniquement sur une partie du texte du paragraphe ; par conséquent, seule cette partie du texte est en gras. Si vous avez déjà utilisé le langage HTML, cela doit vous sembler familier.

Comme le montre l’illustration ci-dessus, plusieurs fonctionnalités sont intégrées aux documents dynamiques :

  • Recherche : permet à l’utilisateur d’effectuer une recherche en texte intégral sur l’ensemble d’un document.

  • Mode d’affichage : l’utilisateur peut sélectionner son mode d’affichage préféré parmi le mode d’affichage page unique (page par page), deux pages à la fois (format livre ouvert) ou défilement continu (sans marge inférieure). Pour plus d’informations sur ces modes d’affichage, consultez FlowDocumentReaderViewingMode.

  • Contrôles de navigation des pages : si le mode d’affichage du document utilise des pages, les contrôles de navigation des pages incluent un bouton pour accéder à la page suivante (flèche Bas) ou à la page précédente (flèche Haut), ainsi qu’une indication du numéro de la page active et du nombre total de pages. Vous pouvez aussi faire défiler les pages à l’aide des touches de direction du clavier.

  • Zoom : les contrôles de zoom permettent à l’utilisateur d’augmenter ou de diminuer le niveau de zoom en cliquant sur les boutons plus ou moins, respectivement. Les contrôles de zoom incluent également un curseur pour ajuster le niveau de zoom. Pour plus d’informations, consultez Zoom.

Ces fonctionnalités peuvent être modifiées selon le contrôle utilisé pour héberger le contenu dynamique. La section suivante décrit les différents contrôles.

Types de documents dynamiques

L’affichage et l’apparence du contenu des documents dynamiques dépendent de l’objet utilisé pour héberger le contenu dynamique. Il existe quatre contrôles qui prennent en charge l’affichage du contenu de flux : FlowDocumentReader, , FlowDocumentPageViewerRichTextBox, et FlowDocumentScrollViewer. Ces contrôles sont brièvement décrits ci-dessous.

Remarque

FlowDocument est nécessaire pour héberger directement le contenu du flux. Ainsi, tous ces contrôles d’affichage consomment un FlowDocument pour activer l’hébergement de contenu de flux.

FlowDocumentReader

FlowDocumentReader inclut des fonctionnalités qui permettent à l’utilisateur de choisir dynamiquement entre différents modes d’affichage, notamment un mode d’affichage monopage (page à la fois), un mode d’affichage à deux pages à l’heure (format de lecture de livres) et un mode d’affichage continu (sans fond). Pour plus d’informations sur ces modes d’affichage, consultez FlowDocumentReaderViewingMode. Si vous n’avez pas besoin de la possibilité de basculer dynamiquement entre différents modes d’affichage et FlowDocumentPageViewerFlowDocumentScrollViewer de fournir des visionneuses de contenu de flux plus légères qui sont fixes dans un mode d’affichage particulier.

FlowDocumentPageViewer et FlowDocumentScrollViewer

FlowDocumentPageViewer affiche le contenu en mode d’affichage de page à temps, tandis qu’il FlowDocumentScrollViewer affiche le contenu en mode de défilement continu. Les deux FlowDocumentPageViewer sont FlowDocumentScrollViewer fixés à un mode d’affichage particulier. Comparez à , qui inclut des fonctionnalités qui permettent à FlowDocumentReaderl’utilisateur de choisir dynamiquement entre différents modes d’affichage (comme fourni par l’énumération FlowDocumentReaderViewingMode ), au coût d’être plus gourmand en ressources que FlowDocumentPageViewer ou FlowDocumentScrollViewer.

Par défaut, une barre de défilement verticale est toujours affichée et une barre de défilement horizontale apparaît si nécessaire. L’interface utilisateur par défaut pour FlowDocumentScrollViewer laquelle il n’inclut pas de barre d’outils ; toutefois, la IsToolBarVisible propriété peut être utilisée pour activer une barre d’outils intégrée.

RichTextBox

Vous utilisez un RichTextBox moment où vous souhaitez autoriser l’utilisateur à modifier le contenu du flux. Par exemple, si vous vouliez créer un éditeur qui permettait à un utilisateur de manipuler des éléments tels que des tables, une mise en forme italique et en gras, etc. vous utiliseriez un RichTextBox. Pour plus d’informations, consultez Vue d’ensemble de RichTextBox.

Remarque

Le contenu de flux à l’intérieur d’un ne RichTextBox se comporte pas exactement comme le contenu de flux contenu dans d’autres contrôles. Par exemple, il n’existe aucune colonne dans un RichTextBox comportement de redimensionnement automatique. En outre, les fonctionnalités intégrées de contenu de flux telles que la recherche, le mode d’affichage, la navigation de page et le zoom ne sont pas disponibles dans un RichTextBox.

Création de contenu dynamique

Le contenu de flux peut être complexe, constitué de différents éléments, notamment du texte, des images, des tableaux et même UIElement des classes dérivées telles que des contrôles. Pour comprendre comment créer du contenu dynamique complexe, les points suivants sont essentiels :

  • Classes liées au contenu dynamique : chaque classe utilisée dans le contenu dynamique a un rôle spécifique. En outre, la relation hiérarchique entre les classes vous permet de comprendre comment elles sont utilisées. Par exemple, les classes dérivées de la Block classe sont utilisées pour contenir d’autres objets tandis que les classes dérivées d’objets Inline contenant des objets affichés.

  • Schéma du contenu : un document dynamique peut nécessiter un nombre important d’éléments imbriqués. Le schéma du contenu indique les relations parent/enfant possibles entre les éléments.

Les sections suivantes décrivent en détail chacun des points ci-dessus.

Le diagramme ci-dessous contient les objets les plus souvent utilisés avec du contenu dynamique :

Diagram: Flow content element class hierarchy

Pour faciliter la gestion du contenu dynamique, il existe deux catégories principales :

  1. Classes dérivées de Block : elles sont également appelées « éléments de contenu Block » ou simplement « éléments Block ». Les éléments qui héritent Block peuvent être utilisés pour regrouper des éléments sous un parent commun ou pour appliquer des attributs communs à un groupe.

  2. Classes dérivées d’Inline : elles sont également appelées « éléments de contenu Inline » ou simplement « éléments Inline ». Les éléments qui héritent Inline sont contenus dans un élément Block ou un autre élément inline. Les éléments Inline sont souvent utilisés comme conteneur direct du contenu restitué à l’écran. Par exemple, un Paragraph (élément Block) peut contenir un Run (élément inline), mais le Run texte affiché à l’écran.

Chaque classe de ces deux catégories est brièvement décrite ci-dessous.

Classes dérivées de Block

Paragraph

Paragraph est généralement utilisé pour regrouper du contenu dans un paragraphe. L’utilisation la plus courante et la plus simple de Paragraph consiste à créer un paragraphe de texte.

<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

Toutefois, vous pouvez également contenir d’autres éléments dérivés inline, comme vous le verrez ci-dessous.

Section

Section est utilisé uniquement pour contenir d’autres Blockéléments dérivés. Il n’applique aucune mise en forme par défaut aux éléments qu’il contient. Toutefois, toutes les valeurs de propriété définies sur une Section application s’appliquent à ses éléments enfants. Une section vous permet également d’itérer par programmation dans sa collection enfant. Section est utilisé de la même manière que la <balise DIV> en HTML.

Dans l’exemple ci-dessous, trois paragraphes sont définis sous un Section. La section a une Background valeur de propriété rouge, par conséquent, la couleur d’arrière-plan des paragraphes est également rouge.

<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

BlockUIContainerpermet aux éléments (c.-à-d. aButton) d’être incorporés UIElement dans le contenu de flux dérivé du bloc. InlineUIContainer (voir ci-dessous) est utilisé pour incorporer UIElement des éléments dans le contenu de flux dérivé inline. BlockUIContainer et InlineUIContainer sont importants, car il n’existe aucun autre moyen d’utiliser un UIElement contenu de flux, sauf s’il est contenu dans l’un de ces deux éléments.

L’exemple suivant montre comment utiliser l’élément pour héberger UIElement des objets dans le BlockUIContainer contenu du flux.

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

La figure suivante montre comment cet exemple s’affiche :

Screenshot that shows a UIElement embedded in flow content.

Liste

List est utilisé pour créer une liste à puces ou numérique. Définissez la MarkerStyle propriété sur une TextMarkerStyle valeur d’énumération pour déterminer le style de la liste. L’exemple ci-dessous montre comment créer une liste simple.

<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

Remarque

List est le seul élément de flux qui utilise les ListItemCollection éléments enfants pour gérer les éléments enfants.

Table

Table est utilisé pour créer une table. Table est similaire à l’élément Grid , mais il a plus de fonctionnalités et, par conséquent, nécessite une surcharge de ressources accrue. Comme Grid il s’agit d’un UIElement, il ne peut pas être utilisé dans le contenu du flux, sauf s’il est contenu dans un BlockUIContainer ou InlineUIContainer. Pour plus d’informations sur , consultez Vue d’ensemble Tabledu tableau.

Classes dérivées d’Inline

Exécuter

Run est utilisé pour contenir du texte non mis en forme. Vous pouvez vous attendre à ce que Run les objets soient largement utilisés dans le contenu de flux. Toutefois, dans le balisage, Run les éléments ne doivent pas être utilisés explicitement. Run doit être utilisé lors de la création ou de la manipulation de documents de flux à l’aide du code. Par exemple, dans le balisage ci-dessous, le premier Paragraph spécifie explicitement l’élément Run alors que la seconde ne le fait pas. Les deux paragraphes génèrent le même résultat.

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

Remarque

À compter du .NET Framework 4, la Text propriété de l’objet Run est une propriété de dépendance. Vous pouvez lier la Text propriété à une source de données, telle qu’un TextBlock. La Text propriété prend entièrement en charge la liaison unidirectionnelle. La Text propriété prend également en charge la liaison bidirectionnelle, à l’exception de RichTextBox. Pour obtenir un exemple, consultez Run.Text.

Span

Span regroupe d’autres éléments de contenu inline ensemble. Aucun rendu inhérent n’est appliqué au contenu d’un Span élément. Toutefois, les éléments qui héritent de Span l’inclusionHyperlink, BoldItalic et Underline appliquent la mise en forme au texte.

Voici un exemple d’utilisation d’un Span contenu inline incluant du texte, un Bold élément et un 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>

La capture d’écran suivante montre le rendu de cet exemple.

Screenshot: Rendered Span example

InlineUIContainer

InlineUIContainerUIElement permet aux éléments (par exemple, un contrôle comme Button) d’être incorporés dans un Inline élément de contenu. Cet élément est l’équivalent inline décrit BlockUIContainer ci-dessus. Voici un exemple qui utilise InlineUIContainer pour insérer un Button inline dans un 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

Remarque

InlineUIContainer n’a pas besoin d’être utilisé explicitement dans le balisage. Si vous l’omettez, une InlineUIContainer opération est créée quand le code est compilé.

Figure et Floater

Figure et Floater sont utilisés pour incorporer du contenu dans des documents flow avec des propriétés de placement qui peuvent être personnalisées indépendamment du flux de contenu principal. Figure ou Floater des éléments sont souvent utilisés pour mettre en surbrillance ou accentuer des parties de contenu, pour héberger des images de prise en charge ou d’autres contenus dans le flux de contenu principal, ou pour injecter du contenu faiblement lié comme les publicités.

L’exemple suivant montre comment incorporer un Figure élément dans un paragraphe de texte.

<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

L’illustration suivante montre le rendu de cet exemple.

Screenshot: Figure example

Figure et Floater diffèrent de plusieurs façons et sont utilisés pour différents scénarios.

Figure :

  • Positionnable : vous pouvez placer ses ancres horizontale et verticale de façon à l’ancrer par rapport à la page, au contenu, à la colonne ou au paragraphe. Vous pouvez également utiliser ses propriétés et VerticalOffset ses HorizontalOffset propriétés pour spécifier des décalages arbitraires.

  • Est sizable pour plusieurs colonnes : vous pouvez définir Figure la hauteur et la largeur sur plusieurs de pages, de contenu ou de hauteur ou de largeur de colonne. Notez que, dans les deux premiers cas, les multiples supérieurs à 1 ne sont pas autorisés. Par exemple, vous pouvez définir la largeur d’une Figure page « 0,5 » ou « 0,25 content » ou « 2 Column ». Vous pouvez également définir des valeurs en pixels absolues pour la hauteur et la largeur.

  • Ne pagine pas : si le contenu à l’intérieur d’un élément Figure ne correspond pas à l’intérieur Figure, il affiche le contenu qui convient et le contenu restant est perdu.

Floater :

  • Non positionnable : cet élément s’affiche dans l’espace disponible, quel qu’il soit. Vous ne pouvez pas définir le décalage ou l’ancre un Floater.

  • Impossible de dimensionner plusieurs colonnes : par défaut, Floater les tailles sont d’une colonne. Il a une Width propriété qui peut être définie sur une valeur de pixel absolue, mais si cette valeur est supérieure à une largeur de colonne, elle est ignorée et le floater est dimensionné à une colonne. Vous pouvez la dimensionner à moins d’une colonne en définissant la largeur correcte des pixels, mais le dimensionnement n’est pas relatif aux colonnes. Par conséquent, « 0,5Column » n’est pas une expression valide pour Floater la largeur. Floater n’a pas de propriété de hauteur et sa hauteur ne peut pas être définie, sa hauteur dépend du contenu

  • Floater paginés : si son contenu à sa largeur spécifiée s’étend à plus de 1 hauteur de colonne, le flotteur saute et pagine vers la colonne suivante, la page suivante, etc.

Figure est un bon endroit pour placer du contenu autonome dans lequel vous souhaitez contrôler la taille et le positionnement, et sont confiants que le contenu s’adaptera à la taille spécifiée. Floater est un bon endroit pour mettre du contenu plus libre qui circule de manière similaire au contenu de la page principale, mais qui est séparé de celui-ci.

LineBreak

LineBreak provoque un saut de ligne dans le contenu du flux. L'exemple suivant montre l'utilisation de 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>

La capture d’écran suivante montre le rendu de cet exemple.

Screenshot: LineBreak example

Éléments de collection de flux

Dans la plupart des exemples ci-dessus, le BlockCollection contenu de flux est InlineCollection utilisé par programmation. Par exemple, pour ajouter des éléments à un Paragraph, vous pouvez utiliser la syntaxe :

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

Cela ajoute un Run au InlineCollectionParagraph. Il s’agit de la même chose que l’implicite Run trouvée à l’intérieur d’un Paragraph balisage :

<Paragraph>
Some Text
</Paragraph>

Par exemple, BlockCollectionl’exemple suivant crée une nouvelle Section méthode, puis utilise la méthode Add pour ajouter un nouveau Paragraph contenu 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...")))

En plus d’ajouter des éléments à une collection de flux, vous pouvez aussi en supprimer. L’exemple suivant supprime le dernier Inline élément du Span.

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

L’exemple suivant efface tout le contenu (Inline éléments) du Span.

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

Quand vous utilisez du contenu dynamique par programmation, vous employez certainement très souvent ces collections.

Si un élément de flux utilise un InlineCollection (Inlines) ou BlockCollection (Blocks) pour contenir ses éléments enfants dépend du type d’éléments enfants (Block ou Inline) pouvant être contenu par le parent. Les règles relatives à la relation contenant-contenu pour les éléments de contenu dynamique sont résumées dans le schéma du contenu présenté à la section suivante.

Remarque

Il existe un troisième type de collection utilisé avec le contenu de flux, mais ListItemCollectioncette collection n’est utilisée qu’avec un List. En outre, il existe plusieurs collections utilisées avec Table. Pour plus d’informations, consultez Vue d’ensemble de Table.

Schéma du contenu

Étant donné le nombre d’éléments de contenu dynamique, il est parfois difficile de savoir quel type d’éléments enfants peut être contenu dans un élément. Le diagramme suivant récapitule les règles relatives à la relation contenant-contenu pour les éléments de contenu dynamique. Les flèches représentent les relations parent/enfant possibles.

Diagram: Flow content containment schema

Comme le montre le diagramme ci-dessus, les enfants autorisés pour un élément ne sont pas nécessairement déterminés par le fait qu’il s’agit d’un Block élément ou d’un Inline élément. Par exemple, un Span (élément Inline ) ne peut avoir Inline que des éléments enfants, tandis qu’un Figure (également un Inline élément) ne peut avoir Block que des éléments enfants. Par conséquent, un diagramme est utile pour déterminer rapidement quel élément peut être contenu dans un autre. Par exemple, utilisons le diagramme pour déterminer comment construire le contenu de flux d’un RichTextBox.

1. Un RichTextBox doit contenir un FlowDocument objet dérivé à son tour Block. Voici le segment correspondant extrait du diagramme ci-dessus.

Diagram: RichTextBox containment rules

À ce stade, le balisage peut ressembler à ceci.

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

2. Selon le diagramme, il existe plusieurs Block éléments à choisir parmi lesquels inclure Paragraph, Section, Table, Listet BlockUIContainer (voir les classes dérivées de bloc ci-dessus). Supposons que nous voulons un Table. Selon le diagramme ci-dessus, un Table contient des TableRowGroup éléments contenant TableRow , qui contiennent des éléments qui contiennent TableCell un Blockobjet dérivé. Vous trouverez ci-dessous le segment correspondant à Table partir du diagramme ci-dessus.

Diagram: Parent/child schema for Table

Le balisage correspondant est indiqué ci-dessous.

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

3. Là encore, un ou plusieurs Block éléments sont requis sous un TableCell. Pour simplifier, insérons du texte dans la cellule. Nous pouvons le faire à l’aide d’un ParagraphRun élément. Voici les segments correspondants du diagramme montrant qu’un Paragraph élément peut prendre un Inline élément et qu’un Run (élément Inline ) ne peut prendre que du texte brut.

Diagram: Parent/child schema for Paragraph

Diagram: Parent/Child schema for Run

Le balisage de l’exemple complet est indiqué ci-dessous.

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

Personnalisation du texte

Généralement, le texte est le type de contenu le plus fréquent dans un document dynamique. Même si les objets décrits ci-dessus permettent de contrôler la plupart des aspects concernant la restitution du texte, il existe d’autres méthodes, décrites dans cette section, destinées à personnaliser le texte.

Ornements de texte

Les ornements de texte vous permettent d’appliquer au texte les effets suivants : souligné, ligne au-dessus, ligne de base et barré (consultez les images ci-dessous). Ces décorations sont ajoutées à l’aide de la TextDecorations propriété exposée par un certain nombre d’objets, notamment Inline, Paragraph, TextBlocket TextBox.

L'exemple suivant montre comment définir la propriété TextDecorations d'un 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

La figure suivante montre le rendu de cet exemple.

Screenshot: Text with default strikethrough effect

Les illustrations suivantes affichent les rendus respectifs des ornements Overline (ligne au-dessus), Baseline (ligne de base) et Underline (souligné).

Screenshot: Overline TextDecorator

Screenshot: Default baseline effect on text

Screenshot: Text with default underline effect

Typographie

La Typography propriété est exposée par la plupart du contenu lié au flux, y compris TextElement, FlowDocument, TextBlocket TextBox. Cette propriété est utilisée pour contrôler les caractéristiques/variations typographiques de texte (en d’autres termes, petites ou grandes majuscules, exposants et indices, etc).

L’exemple suivant montre comment définir l’attribut Typography , à l’aide Paragraph de l’exemple d’élément.

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

La figure suivante montre le rendu de cet exemple.

Screenshot showing text with altered typography.

Par contraste, l’illustration suivante montre comment s’affiche un exemple similaire avec des propriétés typographiques par défaut.

Screenshot showing text with default typography.

L’exemple suivant montre comment définir la Typography propriété par programmation.

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

Pour plus d’informations sur la typographie, consultez Typographie dans WPF.

Voir aussi