This article is currently in the process of being translated into Portuguese (~99% done).
The RichTextBox control
Até agora, analisamos apenas os wrappers somente leitura para o FlowDocument, mas o WPF também inclui um controle que torna um FlowDocument editável: O controle RichTextBox.
Você pode adicionar um RichTextBox diretamente à janela, sem qualquer conteúdo - nesse caso, ele criará automaticamente uma instância do FlowDocument que você estará editando. Alternativamente, você pode envolver uma instância FlowDocument com o RichTextBox e, assim, controlar o conteúdo inicial. Poderia ser assim:
<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>
Com este exemplo, você pode começar a editar seu conteúdo rich text imediatamente. No entanto, agora que o conteúdo não é mais somente leitura, é obviamente interessante como você pode manipular o texto, bem como trabalhar com a seleção. Nós vamos investigar isso agora.
Outro aspecto interessante é, claro, trabalhar com as várias possibilidades de formatação - vamos analisar isso no próximo artigo, onde implementamos um pequeno editor de texto rico, mas totalmente funcional.
Trabalhando com texto e seleção
Como o RichTextBox usa um FlowDocument internamente e porque o formato rich text é obviamente mais complicado do que texto simples, trabalhar com texto e seleções não é tão fácil quanto o controle WPF TextBox.
O próximo exemplo fornecerá um conjunto de funcionalidades que funciona com o texto e / ou seleção no controle 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 + "'";
}
}
}
Como você pode ver, a marcação consiste em um painel de botões, um RichTextBox e um TextBox na parte inferior, para mostrar o status da seleção atual. Cada um dos quatro botões disponíveis funcionará com o RichTextBox, obtendo ou definindo / substituindo texto, para mostrar como isso é feito.
Em Code-behind, lidamos com os eventos de clique de quatro botões, bem como o evento SelectionChanged para o RichTextBox, que nos permite mostrar estatísticas sobre a seleção atual.
Preste atenção especial ao fato de que, em vez de acessar uma propriedade de texto diretamente no RichTextBox, como faríamos com um TextBox regular, estamos usando objetos TextRange com TextPointer do RichTextBox para obter texto do controle ou a seleção no controle . É assim que funciona com o RichTextBox, que, como já mencionado, não funciona como um TextBox comum em vários aspectos.
Espaçamento de parágrafo
Outra coisa que você deve ter notado ao trabalhar com o RichTextBox é o fato de que quando você pressiona Enter para iniciar um novo parágrafo, este parágrafo deixará uma linha vazia entre o antigo e o novo parágrafo. Permita-me ilustrar com uma captura de tela, onde eu inseri três linhas de texto, cada uma separada por apenas uma tecla Enter:
Esse é um comportamento normal para um editor de texto trabalhando em parágrafos, mas dependendo de como e onde você usa o RichTextBox, pode ser confuso para seus usuários que uma única pressão Enter resulte em uma quantidade tão grande de espaço entre as linhas.
Felizmente, é muito fácil de corrigir. Os espaços extras vêm do fato de os parágrafos terem uma margem padrão maior que zero, então corrigi-lo é tão simples quanto mudar essa propriedade, o que podemos fazer com um 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>
Agora as linhas não têm espaço extra ao redor delas, e se você quiser, você pode colocar o estilo na janela ou mesmo no App.xaml, se você quer que ele trabalhe para mais do que apenas um único RichTextBox.
Resumo
O RichTextBox é fácil de usar, tem muitos recursos imediatos e pode ser facilmente usado se você deseja criar um editor de rich text com todos os recursos. No próximo artigo, vamos dar uma olhada nisso! Isso também nos levará em torno de assuntos importantes, como carregar e salvar texto de um RichTextBox e como afetar a formatação de texto no controle.