到目前为止,我们只看了FlowDocument的只读包装器,但WPF还包含一个使FlowDocument可编辑的控件:RichTextBox控件。
您可以直接向窗口添加RichTextBox,而不包含任何内容 - 在这种情况下,它将自动创建您将要编辑的FlowDocument实例。 您也可以修改RichTextBox包装的FlowDocument实例,改变初始内容。 它看起来像这样:
<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>
通过此示例,您可以立即开始编辑富文本内容。 现在内容不再是只读的,如何操作文本以及使用选择显然很有趣。 我们现在研究一下。
另一个有趣的地方是使用各种格式的能力 - 我们将在下一章中研究,我们实际上实现了一个小而功能齐全的富文本编辑器。
因为RichTextBox在内部使用FlowDocument,并且富文本格式比纯文本更复杂,所以使用文本和选择并不像WPF TextBox控件那么容易。
下一个示例将展示一系列功能,这些功能与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 + "'";
}
}
}
如您所见,标记由一组按钮、一个RichTextBox和一个在底部的TextBox组成,以显示当前的选择状态。 四个可用按钮中的每一个都可以获取或设置/替换文本来使用RichTextBox,以向您展示怎么做。
在后台代码中,我们处理了四个按钮的单击事件,以及RichTextBox的SelectionChanged事件,它允许我们显示有关当前选择的统计信息。
特别要注意的是,我们不是直接访问RichTextBox的文本属性,不能像使用常规TextBox那样,我们使用来自RichTextBox的TextPointer的TextRange对象来获取控件中的文本或控件中的选择。 他们与RichTextBox一起工作,如前所述,RichTextBox在这些方面不像常规TextBox那样。
您在使用RichTextBox时可能注意到,当您按Enter键开始新段落时,将在旧段落和新段落之间留下空行。 请允许我用截图说明,我输入了三行文本,每行只用一个Enter键分隔:
对于使用段落的文本编辑器而言,这是正常的,但根据您使用RichTextBox的方式和位置,对于您的用户来说,单个Enter会在行之间产生如此大的空间可能会让您感到困惑。
幸运的是它很容易修复。 额外的空白来自段落的默认边距比零大很多,因此修复它就像更改属性一样简单,我们可以使用样式来做,如下所示:
<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>
现在这些行周围没有额外的空白,如果您愿意,可以将样式放在窗口中,也可以放在App.xaml中,如果您希望它不仅仅适用于单个RichTextBox。
RichTextBox非常容易使用,有许多开箱即用的功能,您可以使用它轻松创建功能齐全的富文本编辑器。 在下一章中,我们将这么做! 这也将使我们了解重要的主题,例如RichTextBox加载和保存文本以及如何改变控件中文本的格式。