TOC

This article is currently in the process of being translated into French (~58% done).

Contrôles RichText:

Le contrôle RichTextBox

Jusqu'à présent, nous avons seulement travaillé avec les contrôles en lecture seule pour le FlowDocument, cependant, WPF inclut aussi un contrôle qui rend un FlowDocument éditable : le contrôle RichTextBox.

Vous pouvez directement ajouter un RichTextBox à la fenêtre, sans aucun contenu - dans ce cas, celui-ci créera automatiquement une instance de FlowDocument que vous pourrez éditer. Vous pouvez également placer votre instance de FlowDocument dans le RichTextBox et contrôler au travers de celui-ci le contenu initial. Cela pourrait ressembler à ceci :

<Window x:Class="WpfTutorialSamples.Rich_text_controls.RichTextBoxSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="RichTextBoxSample" Height="200" Width="300">
    <Grid>
        <RichTextBox Margin="10">
            <FlowDocument>
                <Paragraph FontSize="36">Hello, world!</Paragraph>
                <Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">Thanks to the RichTextBox control, this FlowDocument is completely editable!</Paragraph>
            </FlowDocument>
        </RichTextBox>
    </Grid>
</Window>

Avec cet exemple, vous pouvez directement commencer à éditer votre contenu de texte riche. Cependant, maintenant que le contenu n'est plus en lecture seule, il serait intéressant de savoir comment manipuler le texte, comme de travailler avec la sélection. C'est ce à quoi nous allons nous intéresser à présent.

Un autre aspect intéressant est bien sûr de travailler avec les diverses possibilités de formatage - nous nous intéresserons à cela dans le prochain article, où nous implémenterons en fait un petit, mais complètement fonctionnel, éditeur de texte riche.

Travailler avec le texte et la sélection

Parce que le contrôle RichTextBox utilise un FlowDocument interne, et parce que le format de texte riche est bien entendu plus compliqué que le texte simple, travailler avec le texte et les sélections n'est pas aussi simple que pour le contrôle TextBox WPF.

L'exemple suivant montre quelques fonctionnalités qui fonctionnent avec le texte et/ou la sélection pour le contrôle RichTextBox :

<Window x:Class="WpfTutorialSamples.Rich_text_controls.RichTextBoxTextSelectionSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="RichTextBoxTextSelectionSample" Height="300" Width="400">
    <DockPanel>
        <WrapPanel DockPanel.Dock="Top">
            <Button Name="btnGetText" Click="btnGetText_Click">Get text</Button>
            <Button Name="btnSetText" Click="btnSetText_Click">Set text</Button>
            <Button Name="btnGetSelectedText" Click="btnGetSelectedText_Click">Get sel. text</Button>
            <Button Name="btnSetSelectedText" Click="btnSetSelectedText_Click">Replace sel. text</Button>
        </WrapPanel>
        <TextBox DockPanel.Dock="Bottom" Name="txtStatus" />
        <RichTextBox Name="rtbEditor" SelectionChanged="rtbEditor_SelectionChanged">
            <FlowDocument>
                <Paragraph FontSize="36">Hello, world!</Paragraph>
                <Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">Thanks to the RichTextBox control, this FlowDocument is completely editable!</Paragraph>
            </FlowDocument>
        </RichTextBox>
    </DockPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace WpfTutorialSamples.Rich_text_controls
{
	public partial class RichTextBoxTextSelectionSample : Window
	{
		public RichTextBoxTextSelectionSample()
		{
			InitializeComponent();
		}

		private void btnGetText_Click(object sender, RoutedEventArgs e)
		{
			TextRange textRange = new TextRange(rtbEditor.Document.ContentStart, rtbEditor.Document.ContentEnd);
			MessageBox.Show(textRange.Text);
		}

		private void btnSetText_Click(object sender, RoutedEventArgs e)
		{
			TextRange textRange = new TextRange(rtbEditor.Document.ContentStart, rtbEditor.Document.ContentEnd);
			textRange.Text = "Another world, another text!";
		}

		private void btnGetSelectedText_Click(object sender, RoutedEventArgs e)
		{
			MessageBox.Show(rtbEditor.Selection.Text);
		}

		private void btnSetSelectedText_Click(object sender, RoutedEventArgs e)
		{
			rtbEditor.Selection.Text = "[Replaced text]";
		}

		private void rtbEditor_SelectionChanged(object sender, RoutedEventArgs e)
		{
			TextRange tempRange = new TextRange(rtbEditor.Document.ContentStart, rtbEditor.Selection.Start);
			txtStatus.Text = "Selection starts at character #" + tempRange.Text.Length + Environment.NewLine;
			txtStatus.Text += "Selection is " + rtbEditor.Selection.Text.Length + " character(s) long" + Environment.NewLine;
			txtStatus.Text += "Selected text: '" + rtbEditor.Selection.Text + "'";
		}
	}
}

Comme vous pouvez le voir, le balisage consiste en un panel de boutons, un RichTextBox et un TextBox en bas, pour afficher le statut actuel de la sélection. Chacun des quatre boutons disponibles travaillera avec le RichTextBox soit en obtenant ou en assignant/remplaçant le texte, afin d'afficher comment cela s'est fait.

Dans le code-behind, nous gérons les quatre événements Click des boutons, tout comme l'événement SelectionChanged du RichTextBox, ce qui nous permet d'afficher des statistiques sur la sélection actuelle.

Portez une attention particulière au fait que, au lieu d'accéder directement à une propriété textuelle du RichTextBox, comme nous le faisons pour un TextBox normal, nous utilisons ici des objets TextRange avec des TextPointer depuis le RichTextBox afin d'obtenir du texte depuis le contrôle ou la sélection dans le contrôle. Ceci est simplement comment cela fonctionne avec le RichTextBox, qui, comme nous l'avons déjà mentionné, ne fonctionne pas comme un TextBox normal de part de nombreux aspects.

Espacement des paragraphes

Another thing you may have noticed when working with the RichTextBox, is the fact that when you press Enter to start a new paragraph, this paragraph will leave an empty line between the old and the new paragraph. Allow me to illustrate with a screenshot, where I've entered three lines of text, each just separated by a single Enter key press:

This is normal behavior for a text editor working in paragraphs, but depending on how and where you use the RichTextBox, it might be confusing for your users that a single Enter press results in such a large amount of space between the lines.

Fortunately, it's very easy to fix. The extra spaces comes from the fact that paragraphs have a default margin bigger than zero, so fixing it is as simple as changing this property, which we can do with a style, like this:

<Window x:Class="WpfTutorialSamples.Rich_text_controls.RichTextBoxParagraphSpacingSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="RichTextBoxParagraphSpacingSample" Height="150" Width="300">
    <Grid>
        <RichTextBox Margin="10">
            <RichTextBox.Resources>
                <Style TargetType="{x:Type Paragraph}">
                    <Setter Property="Margin" Value="0" />
                </Style>
            </RichTextBox.Resources>
        </RichTextBox>
    </Grid>
</Window>

Now the lines don't have extra space around them, and if you want, you can place the style in the window or even in App.xaml, if you want it to work for more than just a single RichTextBox.

En résumé

The RichTextBox is easy to use, has lots of features straight out of the box, and can easily be used if you wish to create a fully featured rich text editor. In the next article, we'll have a look at doing just that! This will also get us around important subjects such as loading and saving text from a RichTextBox and how to affect formatting of text in the control.

This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!