This article has been localized into Polish by the community.
Kontrolka RichTextBox
Do teraz widzieliśmy tylko dokumenty FlowDocument przeznaczone tylko do odczytu, ale WPF posiada również kontrolkę, która umożliwia edycję dokumentu FlowDocument: Kontrolkę RichTextBox.
Można dodać RichTextBox od razu do okna, bez żadnej wypełnienia - w takim przypadku automatycznie zostanie utworzona instancja FlowDocument, którą będziesz edytować. Alternatywnie można owinąć instancję FlowDocument za pomocą RichTextBox i w ten sposób kontrolować początkową jego zawartość. Może to wyglądać tak:
<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>
W tym przykładzie można od razu zacząć edytować Rich Text. Jednak teraz, gdy tekst nie jest już tylko do odczytu, warto interesujące jest, w jaki sposób można manipulować tekstem i zaznaczeniem. Zajmiemy się tym teraz.
Innym interesującym aspektem jest oczywiście praca z różnymi możliwościami formatowania - zajmiemy się tym w następnym artykule, w którym faktycznie zaimplementujemy mały, ale w pełni funkcjonalny edytor Rich Text.
Praca z tekstem i zaznaczaniem
Ponieważ RichTextBox używa wewnętrznie dokumentu FlowDocument, a format RichText jest oczywiście bardziej skomplikowany niż zwykły tekst, praca z tekstem i zaznaczeniami nie są tak proste jak w przypadku kontrolki TextBox WPF.
W następnym przykładzie przedstawimy szereg funkcji, które działają z tekstem i/lub zaznaczeniem w kontrolce 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 + "'";
}
}
}
Jak widać, znacznik składa się z panelu buttonów, RichTextBox i TextBox na dole, aby pokazać aktualny stan wyboru. Każdy z czterech dostępnych buttonów będzie współpracował z RichTextBox, pobierając lub ustawiając/zastępując tekst, aby pokazać, jak to się robi.
W Code-behind obsługujemy zdarzenia kliknięcia czterech buttonów, a także zdarzenie SelectionChanged dla RichTextBox, które pozwala nam wyświetlić statystyki na temat aktualnego zaznaczenia.
Zwróć szczególną uwagę na fakt, że zamiast dostępu do właściwości tekstowej bezpośrednio w RichTextBox, tak jak w przypadku zwykłego TextBox, używamy obiektów TextRange z obiektami TextPointer z RichTextBox, aby uzyskać tekst z kontrolki lub zaznaczenia w kontrolce. Tak to po prostu działa w przypadku RichTextBox, który, jak już wspomniano, w kilku aspektach nie działa jak zwykły TextBox.
Odstępy między akapitami
Kolejną rzeczą, którą być może zauważyłeś podczas pracy z RichTextBox, jest fakt, że po naciśnięciu klawisza Enter w celu rozpoczęcia nowego akapitu, akapit ten pozostawia pustą linię pomiędzy starym i nowym akapitem. Pozwól, że zilustruję to zrzutem ekranu, na którym wprowadziłem trzy wiersze tekstu, z których każdy został oddzielone pojedynczym naciśnięciem klawisza Enter:
Jest to normalne zachowanie dla edytora tekstu pracującego w akapitach, ale w zależności od tego, jak i gdzie używasz RichTextBox, może to być mylące dla użytkowników. użytkowników, że pojedyncze naciśnięcie klawisza Enter powoduje powstanie tak dużej ilości miejsca między wierszami.
Na szczęście jest to bardzo łatwe do naprawienia. Dodatkowe spacje wynikają z faktu, że akapity mają domyślny margines większy niż zero, więc naprawienie tego problemu jest tak proste, jak zmiana tej właściwości, co możemy zrobić za pomocą stylu, na przykład takiego jak ten:
<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>
Teraz linie nie mają dodatkowego odstępu wokół siebie, a jeśli chcesz, możesz umieścić styl w oknie lub nawet w App.xaml, jeśli chcesz, aby działał on dla więcej niż tylko dla pojedynczego RichTextBox.
Podsumowanie
RichTextBox jest łatwy w użyciu, ma wiele funkcji zaraz po wyjęciu z pudełka i może być łatwo wykorzystany do stworzenia w pełni funkcjonalnego edytora tekstu. W następnym artykule zajmiemy się właśnie tym! Poruszymy także ważne tematy, takie jak ładowanie i zapisywanie tekstu w RichTextBox oraz jak wpływać na formatowanie tekstu w kontrolce.