RichTextBox 概述

使用 RichTextBox 控件,可以显示或编辑流内容(包括段落、图像、表等)。 本主题介绍 TextBox 类,并提供如何在Extensible Application Markup Language (XAML) 和 C# 中使用它的示例。

本主题包括下列各节。

  • 使用 TextBox 还是 RichTextBox?
  • 创建 RichTextBox
  • 实时拼写检查
  • 上下文菜单
  • 编辑命令
  • 在内容更改时进行检测
  • 保存、加载和打印 RichTextBox 内容
  • 相关主题

使用 TextBox 还是 RichTextBox?

RichTextBoxTextBox 都允许用户编辑文本,但是这两个控件用于不同的情形。 当用户需要编辑带格式的文本、图像、表或其他丰富内容时,最好选择 RichTextBox。 例如,编辑需要格式、图像等内容的文档、文章或博客时,最好使用 RichTextBoxTextBox 要求的系统资源比 RichTextBox 少,因此当只需编辑纯文本(即 用于窗体)时,它是理想选择。 有关 TextBox 的更多信息,请参见 TextBox 概述。 下表汇总了 TextBoxRichTextBox 的主要功能。

控件

实时拼写检查

上下文菜单

格式设置命令,例如 ToggleBold (Ctr+B)

FlowDocument 内容,例如图像、段落、表等。

TextBox

不能。

RichTextBox

**注意:**尽管 TextBox 不支持与格式设置有关的命令,如 ToggleBold (Ctr+B),但是这两个控件都支持许多基本命令,如 MoveToLineEnd)。

后面将更详细地介绍上表中的功能。

创建 RichTextBox

下面的代码演示如何创建可供用户在其中编辑丰富内容的 RichTextBox

<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">

    <!-- A RichTextBox with no initial content in it. -->
    <RichTextBox />

</Page>

具体来说,在 RichTextBox 编辑的内容是流内容。 流内容中可以包含许多类型的元素(包括带格式的文本、图像、列表和表)。 有关流文档的详细信息,请参见流文档概述。 为了包含流内容,可以让 RichTextBox 承载一个 FlowDocument 对象,该对象中同样包含可编辑的内容。 为了演示 RichTextBox 中的流内容,下面的代码演示如何创建具有一个段落和一些加粗文本的 RichTextBox

<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">

  <StackPanel>
    <RichTextBox>
      <FlowDocument>
        <Paragraph>
          This is flow content and you can <Bold>edit me!</Bold>
        </Paragraph>
      </FlowDocument>
    </RichTextBox>
  </StackPanel>

</Page>

Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports System.Windows.Documents
Namespace SDKSample
    Partial Public Class BasicRichTextBoxWithContentExample
        Inherits Page
        Public Sub New()
            Dim myStackPanel As New StackPanel()

            ' Create a FlowDocument to contain content for the RichTextBox.
            Dim myFlowDoc As New FlowDocument()

            ' Create a Run of plain text and some bold text.
            Dim myRun As New Run("This is flow content and you can ")
            Dim myBold As New Bold(New Run("edit me!"))

            ' Create a paragraph and add the Run and Bold to it.
            Dim myParagraph As New Paragraph()
            myParagraph.Inlines.Add(myRun)
            myParagraph.Inlines.Add(myBold)

            ' Add the paragraph to the FlowDocument.
            myFlowDoc.Blocks.Add(myParagraph)

            Dim myRichTextBox As New RichTextBox()

            ' Add initial content to the RichTextBox.
            myRichTextBox.Document = myFlowDoc

            myStackPanel.Children.Add(myRichTextBox)
            Me.Content = myStackPanel

        End Sub
    End Class
End Namespace
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Documents;
namespace SDKSample
{
    public partial class BasicRichTextBoxWithContentExample : Page
    {
        public BasicRichTextBoxWithContentExample()
        {
            StackPanel myStackPanel = new StackPanel();

            // Create a FlowDocument to contain content for the RichTextBox.
            FlowDocument myFlowDoc = new FlowDocument();

            // Create a Run of plain text and some bold text.
            Run myRun = new Run("This is flow content and you can ");
            Bold myBold = new Bold(new Run("edit me!"));

            // Create a paragraph and add the Run and Bold to it.
            Paragraph myParagraph = new Paragraph();
            myParagraph.Inlines.Add(myRun);
            myParagraph.Inlines.Add(myBold);

            // Add the paragraph to the FlowDocument.
            myFlowDoc.Blocks.Add(myParagraph);

            RichTextBox myRichTextBox = new RichTextBox();

            // Add initial content to the RichTextBox.
            myRichTextBox.Document = myFlowDoc;

            myStackPanel.Children.Add(myRichTextBox);
            this.Content = myStackPanel;

        }
    }
}

下图显示的是此示例的呈现效果。

具有内容的 RichTextBox

内容在 RichTextBox 中的显示方式由 ParagraphBold 之类的元素确定。 当用户编辑 RichTextBox 内容时,这些元素会改变此流内容。 有关流内容的功能及其工作方式的更多信息,请参见流文档概述

注意:RichTextBox 内部的流内容的行为并不与其他控件中包含的流内容完全相同。 例如,在 RichTextBox 中不分栏,因此没有自动调整大小行为。 另外,在 RichTextBox 中不能使用内置功能(如搜索、查看模式、页面导航和缩放)。

实时拼写检查

您可以在 TextBoxRichTextBox 中启用实时拼写检查。 启用拼写检查后,会在所有拼写有误的字词下面显示红线(请见下图)。

具有拼写检查功能的 TextBox

若要了解如何启用拼写检查,请参见如何:在文本编辑控件中启用拼写检查

上下文菜单

默认情况下,TextBoxRichTextBox 都会在用户在右击该控件时显示一个上下文菜单。 用户可以使用上下文菜单进行剪切、复制或粘贴(请见下图)。

具有上下文菜单的 TextBox

您可以创建自己的自定义上下文菜单来重写默认行为。 有关更多信息,请参见如何:在 RichTextBox 中定位自定义上下文菜单

编辑命令

用户可以使用编辑命令来为 RichTextBox 中的可编辑内容设置格式。 除了基本编辑命令外,RichTextBox 还包括 TextBox 不支持的格式化命令。 例如,当在 RichTextBox 中进行编辑时,用户可以按 Ctr+B 来切换加粗文本的格式设置。 有关可用命令的完整列表,请参见 EditingCommands。 除了使用键盘快捷键以外,您还可以将命令挂钩到其他控件(如按钮)。 下面的示例演示如何创建简单的工具栏,其中包含用户可用来更改文本格式的按钮。

<Window x:Class="RichTextBoxInputPanelDemo.Window1"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" Height="400" Width="600"
    >
  <Grid>

    <!-- Set the styles for the tool bar. -->
    <Grid.Resources>
      <Style TargetType="{x:Type Button}" x:Key="formatTextStyle">
        <Setter Property="FontFamily" Value="Palatino Linotype"></Setter>
        <Setter Property="Width" Value="30"></Setter>
        <Setter Property="FontSize" Value ="14"></Setter>
        <Setter Property="CommandTarget" Value="{Binding ElementName=mainRTB}"></Setter>
      </Style>

      <Style TargetType="{x:Type Button}" x:Key="formatImageStyle">
        <Setter Property="Width" Value="30"></Setter>
        <Setter Property="CommandTarget" Value="{Binding ElementName=mainRTB}"></Setter>
      </Style>
    </Grid.Resources>

    <DockPanel Name="mainPanel">

      <!-- This tool bar contains all the editing buttons. -->
      <ToolBar Name="mainToolBar" Height="30" DockPanel.Dock="Top">

        <Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Cut" ToolTip="Cut">
          <Image Source="Images\EditCut.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Copy" ToolTip="Copy">
          <Image Source="Images\EditCopy.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Paste" ToolTip="Paste">
          <Image Source="Images\EditPaste.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Undo" ToolTip="Undo">
          <Image Source="Images\EditUndo.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="ApplicationCommands.Redo" ToolTip="Redo">
          <Image Source="Images\EditRedo.png"></Image>
        </Button>

        <Button Style="{StaticResource formatTextStyle}" Command="EditingCommands.ToggleBold" ToolTip="Bold">
          <TextBlock FontWeight="Bold">B</TextBlock>
        </Button>
        <Button Style="{StaticResource formatTextStyle}" Command="EditingCommands.ToggleItalic" ToolTip="Italic">
          <TextBlock FontStyle="Italic" FontWeight="Bold">I</TextBlock>
        </Button>
        <Button Style="{StaticResource formatTextStyle}" Command="EditingCommands.ToggleUnderline" ToolTip="Underline">
          <TextBlock TextDecorations="Underline" FontWeight="Bold">U</TextBlock>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.IncreaseFontSize" ToolTip="Grow Font">
          <Image Source="Images\CharacterGrowFont.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.DecreaseFontSize" ToolTip="Shrink Font">
          <Image Source="Images\CharacterShrinkFont.png"></Image>
        </Button>

        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.ToggleBullets" ToolTip="Bullets">
          <Image Source="Images\ListBullets.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.ToggleNumbering" ToolTip="Numbering">
          <Image Source="Images/ListNumbering.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.AlignLeft" ToolTip="Align Left">
          <Image Source="Images\ParagraphLeftJustify.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.AlignCenter" ToolTip="Align Center">
          <Image Source="Images\ParagraphCenterJustify.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.AlignRight" ToolTip="Align Right">
          <Image Source="Images\ParagraphRightJustify.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.AlignJustify" ToolTip="Align Justify">
          <Image Source="Images\ParagraphFullJustify.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.IncreaseIndentation" ToolTip="Increase Indent">
          <Image Source="Images\ParagraphIncreaseIndentation.png"></Image>
        </Button>
        <Button Style="{StaticResource formatImageStyle}" Command="EditingCommands.DecreaseIndentation" ToolTip="Decrease Indent">
          <Image Source="Images\ParagraphDecreaseIndentation.png"></Image>
        </Button>

      </ToolBar>

      <!-- By default pressing tab moves focus to the next control. Setting AcceptsTab to true allows the 
           RichTextBox to accept tab characters. -->
      <RichTextBox Name="mainRTB" AcceptsTab="True"></RichTextBox>
    </DockPanel>
  </Grid>
</Window>

下图显示的是此示例的显示效果。

具有工具栏的 RichTextBox

在内容更改时进行检测

通常,只要 TextBoxRichTextBox 中的文本发生更改,就应使用 TextChanged 事件进行检测,而不是像您可能预期的那样使用 KeyDown。 有关示例,请参见 如何:检测 TextBox 中的文本何时更改

保存、加载和打印 RichTextBox 内容

下面的示例演示如何将 RichTextBox 的内容保存到文件、如何将该内容重新加载到 RichTextBox 中以及如何打印该内容。 下面是该示例的标记。

<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.SaveLoadPrintRTB" >

  <StackPanel>
    <RichTextBox Name="richTB">
      <FlowDocument>
        <Paragraph>
          <Run>Paragraph 1</Run>
        </Paragraph>
      </FlowDocument>
    </RichTextBox>

    <Button Click="SaveRTBContent">Save RTB Content</Button>
    <Button Click="LoadRTBContent">Load RTB Content</Button>
    <Button Click="PrintRTBContent">Print RTB Content</Button>
  </StackPanel>

</Page>

下面是该示例的隐藏代码。


Imports System
Imports System.IO
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Imports System.Windows.Media

Namespace SDKSample

    Partial Public Class SaveLoadPrintRTB
        Inherits Page

        ' Handle "Save RichTextBox Content" button click.
        Private Sub SaveRTBContent(ByVal sender As Object, ByVal args As RoutedEventArgs)

            ' Send an arbitrary URL and file name string specifying
            ' the location to save the XAML in.
            SaveXamlPackage("C:\test.xaml")
        End Sub

        ' Handle "Load RichTextBox Content" button click.
        Private Sub LoadRTBContent(ByVal sender As Object, ByVal args As RoutedEventArgs)
            ' Send URL string specifying what file to retrieve XAML
            ' from to load into the RichTextBox.
            LoadXamlPackage("C:\test.xaml")
        End Sub

        ' Handle "Print RichTextBox Content" button click.
        Private Sub PrintRTBContent(ByVal sender As Object, ByVal args As RoutedEventArgs)
            PrintCommand()
        End Sub

        ' Save XAML in RichTextBox to a file specified by _fileName
        Private Sub SaveXamlPackage(ByVal _fileName As String)
            Dim range As TextRange
            Dim fStream As FileStream
            range = New TextRange(richTB.Document.ContentStart, richTB.Document.ContentEnd)
            fStream = New FileStream(_fileName, FileMode.Create)
            range.Save(fStream, DataFormats.XamlPackage)
            fStream.Close()
        End Sub

        ' Load XAML into RichTextBox from a file specified by _fileName
        Private Sub LoadXamlPackage(ByVal _fileName As String)
            Dim range As TextRange
            Dim fStream As FileStream
            If File.Exists(_fileName) Then
                range = New TextRange(richTB.Document.ContentStart, richTB.Document.ContentEnd)
                fStream = New FileStream(_fileName, FileMode.OpenOrCreate)
                range.Load(fStream, DataFormats.XamlPackage)
                fStream.Close()
            End If
        End Sub

        ' Print RichTextBox content
        Private Sub PrintCommand()
            Dim pd As New PrintDialog()
            If (pd.ShowDialog() = True) Then
                'use either one of the below      
                pd.PrintVisual(TryCast(richTB, Visual), "printing as visual")
                pd.PrintDocument(((CType(richTB.Document, IDocumentPaginatorSource)).DocumentPaginator), "printing as paginator")
            End If
        End Sub
    End Class
End Namespace
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

namespace SDKSample
{

    public partial class SaveLoadPrintRTB : Page
    {

        // Handle "Save RichTextBox Content" button click.
        void SaveRTBContent(Object sender, RoutedEventArgs args)
        {

            // Send an arbitrary URL and file name string specifying
            // the location to save the XAML in.
            SaveXamlPackage("C:\\test.xaml");
        }

        // Handle "Load RichTextBox Content" button click.
        void LoadRTBContent(Object sender, RoutedEventArgs args)
        {
            // Send URL string specifying what file to retrieve XAML
            // from to load into the RichTextBox.
            LoadXamlPackage("C:\\test.xaml");
        }

        // Handle "Print RichTextBox Content" button click.
        void PrintRTBContent(Object sender, RoutedEventArgs args)
        {
            PrintCommand();
        }

        // Save XAML in RichTextBox to a file specified by _fileName
        void SaveXamlPackage(string _fileName)
        {
            TextRange range;
            FileStream fStream;
            range = new TextRange(richTB.Document.ContentStart, richTB.Document.ContentEnd);
            fStream = new FileStream(_fileName, FileMode.Create);
            range.Save(fStream, DataFormats.XamlPackage);
            fStream.Close();
        }

        // Load XAML into RichTextBox from a file specified by _fileName
        void LoadXamlPackage(string _fileName)
        {
            TextRange range;
            FileStream fStream;
            if (File.Exists(_fileName))
            {
                range = new TextRange(richTB.Document.ContentStart, richTB.Document.ContentEnd);
                fStream = new FileStream(_fileName, FileMode.OpenOrCreate);
                range.Load(fStream, DataFormats.XamlPackage);
                fStream.Close();
            }
        }

        // Print RichTextBox content
        private void PrintCommand()
        {
            PrintDialog pd = new PrintDialog();
            if ((pd.ShowDialog() == true))
            {
                //use either one of the below      
                pd.PrintVisual(richTB as Visual, "printing as visual");
                pd.PrintDocument((((IDocumentPaginatorSource)richTB.Document).DocumentPaginator), "printing as paginator");
            }
        }
    }
}

请参见

概念

TextBox 概述

其他资源

RichTextBox 帮助主题