Vue d'ensemble des documents dynamiques

Mise à jour : novembre 2007

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

Cette rubrique comprend les sections suivantes.

  • Description d'un document dynamique
  • Types de documents dynamiques
  • Création de contenu dynamique
  • Classes liées au contenu dynamique
  • Schéma du contenu
  • Personnalisation du texte
  • Rubriques connexes

Description d'un document dynamique

Un document dynamique est conçu pour gérer le rendu du contenu en fonction de la taille de la fenêtre, la résolution du périphérique et d'autres variables d'environnement. En outre, les documents dynamiques possèdent plusieurs fonctionnalités intégrées, par exemple la recherche, les modes d'affichage, qui optimisent la lisibilité et permettent de changer la taille et l'apparence des polices. Les documents dynamiques sont utilisés surtout lorsque 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 lorsque le contenu source doit être fidèlement respecté. Pour plus d'informations sur les différents types de documents, consultez Documents dans Windows Presentation Foundation.

Les schémas ci-dessous montrent un exemple de document dynamique affiché dans des fenêtres de différentes tailles. À chaque fois que la zone d'affichage change, le contenu reflue pour utiliser de façon optimale l'espace disponible.

Nouveau flux de contenu d'un document dynamique

Comme vous le voyez sur les schémas 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 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="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
  <FlowDocument>
    <Paragraph>
      <Bold>Some bold text in the paragraph.</Bold>
      Some text that is not bold.
    </Paragraph>

    <List>
      <ListItem>
        <Paragraph>ListItem 1</Paragraph>
      </ListItem>
      <ListItem>
        <Paragraph>ListItem 2</Paragraph>
      </ListItem>
      <ListItem>
        <Paragraph>ListItem 3</Paragraph>
      </ListItem>
    </List>

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

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

            Paragraph myParagraph = new Paragraph();

            // Add some Bold text to the paragraph
            myParagraph.Inlines.Add(new Bold(new Run("Some bold text in the paragraph.")));

            // Add some plain text to the paragraph
            myParagraph.Inlines.Add(new Run(" Some text that is not bold."));

            // Create a List and populate with three list items.
            List myList = new List();

            // First create paragraphs to go into the list item.
            Paragraph paragraphListItem1 = new Paragraph(new Run("ListItem 1"));
            Paragraph paragraphListItem2 = new Paragraph(new Run("ListItem 2"));
            Paragraph paragraphListItem3 = new Paragraph(new Run("ListItem 3"));

            // Add ListItems with paragraphs in them.
            myList.ListItems.Add(new ListItem(paragraphListItem1));
            myList.ListItems.Add(new ListItem(paragraphListItem2));
            myList.ListItems.Add(new ListItem(paragraphListItem3));

            // Create a FlowDocument with the paragraph and list.
            FlowDocument myFlowDocument = new FlowDocument();
            myFlowDocument.Blocks.Add(myParagraph);
            myFlowDocument.Blocks.Add(myList);

            // Add the FlowDocument to a FlowDocumentReader Control
            FlowDocumentReader myFlowDocumentReader = new FlowDocumentReader();
            myFlowDocumentReader.Document = myFlowDocument;

            this.Content = myFlowDocumentReader;
        }
    }
}

Cet extrait de code est illustré ci-dessous.

Capture d'écran : exemple d'affichage de FlowDocument

Dans cet exemple, le contrôle FlowDocumentReader est utilisé pour héberger le contenu dynamique. Pour plus d'informations sur les contrôles servant à héberger le contenu dynamique, consultez la section Types de documents dynamiques. Les éléments Paragraph, List, ListItem et Bold sont utilisés pour gérer la mise en forme du contenu, selon leur ordre dans le balisage. Par exemple, l'élément Bold s'étend uniquement sur une partie du texte dans le paragraphe ; par conséquent, seule cette partie du texte apparaît 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 de 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 le mode d'affichage défilement continu (sans marge inférieure). Pour plus d'informations sur les 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 page en cours 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 dynamique : FlowDocumentReader, FlowDocumentPageViewer, RichTextBox et FlowDocumentScrollViewer. Ces contrôles sont brièvement décrits ci-après.

Remarque : FlowDocument est requis pour héberger directement le contenu dynamique, donc tous ces contrôles d'affichage utilisent un FlowDocument pour activer l'hébergement du contenu dynamique.

FlowDocumentReader

FlowDocumentReader inclut des fonctionnalités qui permettent à l'utilisateur de choisir dynamiquement entre plusieurs modes d'affichage : mode d'affichage page unique (page par page), deux pages à la fois (format livre ouvert) et mode d'affichage défilement continu (sans marge inférieure). Pour plus d'informations sur les modes d'affichage, consultez FlowDocumentReaderViewingMode. Si vous n'avez pas besoin de basculer dynamiquement entre les différents modes d'affichage, FlowDocumentPageViewer et FlowDocumentScrollViewer fournissent des versions plus allégées d'afficheurs de contenu dynamique qui sont réglées sur un mode d'affichage particulier.

FlowDocumentPageViewer et FlowDocumentScrollViewer

FlowDocumentPageViewer affiche le contenu en mode page par page, alors que FlowDocumentScrollViewer affiche le contenu en mode de défilement continu. FlowDocumentPageViewer et FlowDocumentScrollViewer correspondent chacun à un mode d'affichage particulier. En revanche, FlowDocumentReader inclut des fonctionnalités qui permettent à l'utilisateur de choisir dynamiquement entre plusieurs modes d'affichage (tels que ceux fournis par l'énumération FlowDocumentReaderViewingMode), mais qui en font une application qui consomment beaucoup plus de 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 n'inclut pas de barre d'outils ; toutefois, vous pouvez utiliser la propriété IsToolBarVisible pour activer une barre d'outils intégrée.

RichTextBox

Utilisez RichTextBox lorsque vous souhaitez autoriser l'utilisateur à modifier le contenu dynamique. Par exemple, si vous voulez créer un éditeur qui autorise l'utilisateur à manipuler des éléments tels que les tableaux, les mises en forme (italique, gras), etc, vous devez utiliser RichTextBox. Pour plus d'informations, consultez Vue d'ensemble de RichTextBox.

Remarque : un contenu dynamique placé dans un RichTextBox ne se comporte pas tout à fait de la même façon qu'un contenu dynamique dans d'autres contrôles. Par exemple, RichTextBox ne comporte pas de colonnes et ne permet donc pas de redimensionnement automatique. Par ailleurs, RichTextBox ne dispose pas des fonctionnalités généralement intégrées au contenu dynamique, telles que la recherche, le mode d'affichage, la navigation entre les pages et le zoom.

Création de contenu dynamique

Le contenu dynamique peut être complexe et comprendre des éléments variés, notamment du texte, des images, des tableaux et même des classes dérivées UIElement, par exemple 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 aide à comprendre comment les utiliser. Par exemple, les classes dérivées de la classe Block sont utilisées pour contenir d'autres objets alors que les classes dérivées de Inline contiennent 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.

Classes liées au contenu dynamique

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

Diagramme : hiérarchie de classe d'élément de contenu de flux

Pour faciliter la gestion du contenu dynamique, les objets sont classés dans 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 de la classe Block peuvent être utilisés pour grouper des éléments sous un parent commun ou appliquer des attributs communs à un groupe.

  2. Classes dérivées de Inline : elles sont également appelées « éléments de contenu Inline » ou simplement « éléments Inline ». Les éléments qui héritent de la classe Inline sont soit contenus dans un élément Block, soit un autre élément Inline. Les éléments Inline sont souvent utilisés comme conteneur direct pour le contenu restitué sur l'écran. Par exemple, un Paragraph (élément Block) peut contenir un Run (élément Inline), mais le Run contient en fait le texte restitué sur l'écran.

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

Classes dérivées de Block

Paragraph

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

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

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

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

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

            this.Content = myFlowDocument;
        }
    }
}

Cependant, vous pouvez également inclure des éléments dérivés de Inline, comme vous le verrez ci-dessous.

Section

Section est utilisé uniquement pour contenir d'autres éléments dérivés de Block. Il n'applique pas toute mise en forme par défaut aux éléments qu'il contient. Toutefois, les valeurs de propriété affectées à un Section s'appliquent à ses éléments enfants. Une section vous permet également de parcourir par programme sa collection enfant. Section est utilisé de la même manière que la balise <DIV> en langage HTML.

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

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

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

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

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

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

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

            this.Content = myFlowDocument;
        }
    }
}

BlockUIContainer

BlockUIContainer permet d'incorporer les éléments UIElement (un Button, par exemple) dans le contenu dynamique dérivé de Block. InlineUIContainer (voir ci-dessous) est utilisé pour incorporer des éléments UIElement dans le contenu dynamique dérivé de Inline. BlockUIContainer et InlineUIContainer sont importants car il n'existe aucun autre moyen d'utiliser un UIElement dans le contenu dynamique sauf s'il est contenu dans l'un de ces deux éléments.

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

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

L'illustration suivante montre comment s'affiche cet exemple.

Capture d'écran : UIElement incorporé dans le contenu du flux

Liste

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

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

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

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

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

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

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

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

            this.Content = myFlowDocument;
        }
    }
}

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

Table

Table est utilisé pour créer une table. Table est identique à l'élément Grid mais présente plus de fonctions et, par conséquent, nécessite davantage de ressources. Comme Grid est un UIElement, il ne peut pas être utilisé dans le contenu dynamique sauf s'il est contenu dans un BlockUIContainer ou InlineUIContainer. Pour plus d'informations sur Table, consultez Vue d'ensemble de Table.

Classes dérivées de Inline

Run

Run est utilisé pour contenir du texte non mis en forme. Vous pensez peut-être que les objets Run sont largement utilisés dans le contenu dynamique, cependant les éléments Run ne doivent pas nécessairement être utilisés explicitement dans le balisage. Par exemple, dans le balisage ci-dessous, le premier Paragraph spécifie explicitement l'élément Run, mais pas le second. 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 the Run element in markup. It renders
  the same as a Paragraph with Run used explicitly. 
</Paragraph>

Remarque : Run doit obligatoirement être utilisé lorsque vous créez ou manipulez des documents dynamiques à l'aide du code.

Span

Span regroupe d'autres éléments de contenu Inline. Aucun rendu inhérent n'est appliqué au contenu dans un élément Span. Toutefois, les éléments hérités de Span, notamment Hyperlink, Bold, Italic et Underline appliquent la mise en forme au texte.

Dans l'exemple ci-dessous, Span est utilisé pour contenir du contenu Inline comprenant du texte, un élément Bold et un Button.

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

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

</FlowDocument>

La capture d'écran suivante montre comment s'affiche cet exemple.

Capture d'écran : exemple d'affichage de Span

InlineUIContainer

InlineUIContainer permet d'incorporer les éléments UIElement (un contrôle tel que Button, par exemple) dans un élément de contenu Inline. Cet élément est l'équivalent Inline de l'élément BlockUIContainer décrit ci-dessus. Dans l'exemple ci-dessous, InlineUIContainer est utilisé pour insérer un Button Inline dans un Paragraph.

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

  <Paragraph>
    Text to precede the button...

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

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

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

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

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

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

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

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

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

            this.Content = myFlowDocument;
        }
    }
}

Remarque :InlineUIContainer ne doit pas nécessairement être utilisé explicitement dans le balisage. Si vous l'omettez, un InlineUIContainer sera créé quand même lors de la compilation du code.

Figure et Floater

Figure et Floater sont utilisés pour incorporer du contenu dans des documents dynamiques avec des propriétés de positionnement qui peuvent être personnalisées indépendamment du flux de contenu principal. Les éléments Figure ou Floater sont souvent utilisés pour mettre en surbrillance ou accentuer des parties de contenu, héberger des images ou autres dans le flux de contenu principal ou injecter du contenu vaguement lié, tel que des publicités.

L'exemple suivant montre comment incorporer un élément Figure dans un paragraphe du texte.

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

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

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

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

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

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

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

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

            this.Content = myFlowDocument;
        }
    }
}

L'illustration suivante montre comment s'affiche cet exemple.

Capture d'écran : exemple de figure

Figure et Floater ont des caractéristiques très différentes et sont utilisés pour des scénarios différents.

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 HorizontalOffset et VerticalOffset pour spécifier des offsets arbitraires.

  • Dimensionnable sur plusieurs colonnes : vous pouvez définir la hauteur et la largeur de Figure sous forme de multiples d'une hauteur ou largeur de page, de contenu ou 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'un Figure en lui affectant la valeur « page 0.5 » ou « contenu 0.25 » ou « colonne 2 ». Vous pouvez également choisir des valeurs en pixels absolues pour la hauteur et la largeur.

  • Non paginable : si le contenu d'un Figure ne tient pas dans un Figure, le contenu excédentaire est perdu.

Floater :

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

  • Non dimensionnable sur plusieurs colonnes : par défaut, Floater est dimensionné sur une colonne. Il dispose d'une propriété Width qui peut être définie sur une valeur en pixels absolue, mais si cette valeur est supérieure à une largeur de colonne, elle est ignorée et le floater est dimensionné sur une colonne. Sa taille peut être inférieure à celle d'une colonne si vous définissez la largeur correcte en pixels, mais le dimensionnement ne dépendant pas des colonnes, « colonne 0.5 » n'est pas une expression valide pour la largeur du Floater. Floater n'a pas de propriété de hauteur : sa hauteur ne peut pas être définie et dépend du contenu.

  • Floater peut être paginé : si, à la largeur spécifiée, son contenu dépasse la hauteur d'une colonne, le floater se divise et la pagination reprend sur la colonne suivante, la page suivante, etc.

Figure constitue un emplacement approprié pour du contenu autonome dont vous souhaitez contrôler la taille et le positionnement, si vous êtes certain que ce contenu tiendra dans la taille spécifiée. Floater représente un emplacement adéquat pour du contenu plus flexible avec un flux semblable à celui de la page principale, mais dont il est séparé.

LineBreak

LineBreak insère un saut de ligne dans le contenu du flux. L'exemple suivant montre l'utilisation de l'élément LineBreak.

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

  <Paragraph>
    <LineBreak/>
  </Paragraph>

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

La capture d'écran suivante montre comment s'affiche cet exemple.

Capture d'écran : exemple de LineBreak

Éléments de collection de flux

Dans plusieurs des exemples ci-dessus, les éléments BlockCollection et InlineCollection sont utilisés pour construire du contenu dynamique par programme. Par exemple, pour ajouter des éléments à Paragraph, vous pouvez utiliser la syntaxe suivante :

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

Cela ajoute un Run à InlineCollection de Paragraph. L'effet produit est le même qu'avec le Run implicite situé dans un Paragraph dans le balisage :

<Paragraph>

Some Text

</Paragraph>

Pour montrer l'utilisation de BlockCollection, l'exemple suivant crée un nouveau Section et utilise la méthode Add pour ajouter un nouveau Paragraph au contenu de Section.

Section secx = 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 élément Inline de Span.

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

L'exemple suivant efface tout le contenu (éléments Inline de Span.

spanx.Inlines.Clear();

Lorsque vous construisez du contenu dynamique par programme, vous utiliserez certainement très souvent ces collections.

L'utilisation par un élément de flux d'un InlineCollection (Inlines) ou d'un BlockCollection (Blocks) pour contenir ses éléments enfants dépend du type d'éléments enfants (Block ou Inline) qui peut ê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ée avec le contenu dynamique, ListItemCollection, mais cette collection est utilisée uniquement avec 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

Vu le nombre important 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 schéma ci-dessous résume les règles relatives à la relation contenant-contenu pour les éléments de contenu dynamique. Les flèches représentent les relations parent/enfants possibles.

Diagramme : schéma de relation contenant-contenu du flux

Comme vous pouvez le constater sur le schéma ci-dessus, les enfants autorisés pour un élément ne sont pas nécessairement déterminés par le fait qu'il s'agisse d'un élément Block ou d'un élément Inline. Par exemple, Span (élément Inline) peut avoir uniquement des éléments enfants Inline alors que Figure (également un élément Inline) ne peut avoir que des éléments enfants Block. Par conséquent, ce schéma est très utile pour savoir rapidement quel élément peut être contenu dans un autre. Par exemple, utilisons le schéma pour déterminer comment construire le contenu dynamique d'un RichTextBox.

1. Un RichTextBox doit contenir unFlowDocument qui doit à son tour contenir un objet dérivé de Block. Voici le segment correspondant extrait du schéma ci-dessus.

Diagramme : règles de relation contenant-contenu RichtextBox

À ce stade, le balisage peut ressembler à ceci.

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

2. D'après le schéma, plusieurs éléments Block peuvent être sélectionnés, notamment Paragraph, Section, Table, List et BlockUIContainer (voir classes dérivées de Block ci-dessus). Supposons que nous voulons l'élément Table. Le schéma ci-dessus indique qu'un Table contient un TableRowGroup contenant des éléments TableRow, qui contiennent des éléments TableCell contenant eux-mêmes un objet dérivé de Block. Pour Table, voici le segment correspondant extrait du schéma ci-dessus.

Diagramme : schéma parent/enfant pour 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. Ici encore, un ou plusieurs éléments Block sont requis sous TableCell. Pour simplifier, insérons du texte dans la cellule. Pour cela, nous pouvons utiliser un Paragraph avec un élément Run. Voici les segments correspondants extraits du schéma ci-dessus ; ils montrent qu'un Paragraph peut contenir un élément Inline et qu'un Run (élément Inline) peut uniquement contenir du texte brut.

Diagramme : schéma parent/enfant pour ParagraphDiagramme : schéma parent/enfant pour Run

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

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

      <!-- Normally a table would have multiple rows and multiple
           cells but this code is for demonstration purposes.-->

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


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

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é (voir les images ci-dessous). Ces ornements sont ajoutés à l'aide de la propriété TextDecorations qui est exposée par plusieurs objets, y compris Inline, Paragraph, TextBlock et TextBox.

L'exemple suivant montre comment paramétrer 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;

L'illustration suivante montre comment s'affiche cet exemple.

Capture d'écran : texte avec effet barré par défaut

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

Capture d'écran : Overline TextDecoratorCapture d'écran : effet de la ligne de base par défaut sur le texteCapture d'écran : texte avec effet souligné par défaut

Typographie

La propriété Typography est exposée par la plupart du contenu dynamique, y compris TextElement, FlowDocument, TextBlock et TextBox. Elle est utilisée pour contrôler les caractéristiques/variations typographiques du texte (petites ou grandes majuscules, exposants et indices, etc).

L'exemple suivant montre comment définir l'attribut Typography en utilisant l'élément Paragraph comme exemple.

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

L'illustration suivante montre comment s'affiche cet exemple.

Capture d'écran : texte avec typographie altérée

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

Capture d'écran : texte avec typographie altérée

L'exemple suivant montre comment définir la propriété Typography par programme.

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;

Pour plus d'informations sur la typographie, consultez Typographie dans Windows Presentation Foundation.

Voir aussi

Tâches

SDK Viewer, démonstration

Concepts

Optimisation des performances : texte

Typographie dans Windows Presentation Foundation

Vue d'ensemble du modèle de contenu de TextElement

Vue d'ensemble de RichTextBox

Documents dans Windows Presentation Foundation

Vue d'ensemble de Table

Vue d'ensemble des annotations

Autres ressources

Exemples d'éléments de contenu de flux

Rubriques Comment relatives aux éléments de contenu de flux