-
Rich Text控件:

RichTextBox控件

到目前为止,我们只看了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加载和保存文本以及如何改变控件中文本的格式。