TOC

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

Controles de texto enriquecido:

The RichTextBox control

Hasta ahora, solamente hemos visto los wrappers (envoltorios) de sólo lectura para el FlowDocumet, pero WPF también incluye un control que permite editarlo: El control RichTextBox

Podemos agregar un RichTextBox directamente a la ventana, sin ningún contenido; en ese caso, creará automáticamente una instancia de FlowDocument que editará. Alternativamente, puede ajustar una instancia de FlowDocument con RichTextBox y controlar así el contenido inicial. Podría verse así:

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

Con este ejemplo, puedes comenzar a editar inmediatamente tu RichText. Sin embargo, ahora el contenido ya no será de lectura únicamente, lo cual resulta obvio.

Otro aspecto interesante es, por supuesto, trabajar con varias posibilidades de formato - las cuales serán vistas en el siguiente artículo, en dónde actualmente implementamos un pequeño, pero funcional editor de texto.

Trabajando con texto y selecciones

Ya que el RichTextBox usa internamente un FlowDocument, y además el formato de texto rico es obviamente más complicado que el texto plano, trabajar con texto y selecciones no son tan fáciles para el control TextBox de WPF.

El siguiente ejemplo te mostrará el alcance de la funcionalidad que tiene el RichTextBox al trabajar con texto y/o selección

<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 + "'";
		}
	}
}

Como puedes ver, la aplicación consiste en un panel de botones, un RichTextBox y un TextBox al final para mostrar el estado de la selección actual. Cada uno de los cuatro botones funcionarán con el RichTextBox para: obtener, establecer o reemplazar texto.

En Código subyacente, manejamos los eventos de clic de cuatro botones, así como el evento SelectionChanged para RichTextBox, que nos permite mostrar estadísticas sobre la selección actual.

Preste especial atención al hecho de que, en lugar de acceder a una propiedad de texto directamente en RichTextBox, como haríamos con un TextBox normal, estamos utilizando TextRange objetos con TextPointer del RichTextBox para obtener texto del control o la selección en el control. Así es simplemente como funciona con RichTextBox, que, como ya se mencionó, no funciona como un TextBox normal en varios aspectos.

Espacio entre párrafos

Otra cosa que podemos observar al trabajar con RichTextBox es el hecho de que cuando presiona Entrar para comenzar un nuevo párrafo, este párrafo dejará una línea vacía entre el párrafo antiguo y el nuevo. Permítanme ilustrar con una captura de pantalla, donde ingresé tres líneas de texto, cada una separada por una sola tecla Intro:

Este es un comportamiento normal para un editor de texto que trabaja en párrafos, pero dependiendo de cómo y dónde use RichTextBox, puede ser confuso para los usuarios que una sola tecla Intro genere una gran cantidad de espacio entre las líneas.

Afortunadamente, es muy fácil de arreglar. Los espacios adicionales provienen del hecho de que los párrafos tienen un margen predeterminado mayor que cero, por lo que arreglarlo es tan simple como cambiar esta propiedad, lo que podemos hacer con un estilo como este:

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

Ahora las líneas no tienen espacio adicional a su alrededor, si lo desea, puede colocar el estilo en la ventana o incluso en App.xaml, si desea que funcione para más de un solo RichTextBox.

Resumen

RichTextBox es fácil de usar, tiene muchas características directamente de fábrica y puede usarse fácilmente si desea crear un editor de texto enriquecido con todas las funciones. ¡En el próximo artículo, veremos cómo hacerlo! Esto también nos ayudará a abordar temas importantes como la carga y el ahorro.


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!