WPF 中支持拼写检查的富文本编辑器





5.00/5 (6投票s)
创建一个启用拼写检查的富文本编辑器。
引言
在本文中,我将介绍如何在 WPF 中创建一个启用拼写检查的富文本编辑器。我的主要目标是以最快的速度,通过最少的步骤开发一个富文本编辑器,而无需深入研究 WPF 的极端复杂性。
背景
可以使用 RichTextBox
控件来创建富文本编辑器。RichTextBox
控件允许您处理文本、段落、图像、表格等内容。可以通过以下代码添加富文本框
<RichTextBox Margin="11,100,14,9" Name="richTextBox1"/>
添加拼写检查功能非常简单。您只需将 SpellCheck.IsEnabled
依赖属性设置为 true
,如下所示<RichTextBox Margin="11,100,14,9" Name="richTextBox1" SpellCheck.IsEnabled="True" />
RichTextBox
控件允许您使用 Document
对象来操作其内容。可以使用 RichTextBox
控件的 Document
属性来检索 Document
对象。
使用代码
以下 XAML 代码用于为工具栏图标创建位图资源
<Window.Resources>
<BitmapImage x:Key="newicon" UriSource="new.png"/>
<BitmapImage x:Key="openicon" UriSource="open.png"/>
<BitmapImage x:Key="saveicon" UriSource="save.png"/>
<BitmapImage x:Key="exiticon" UriSource="exit.png"/>
<BitmapImage x:Key="undoicon" UriSource="undo.png"/>
<BitmapImage x:Key="redoicon" UriSource="redo.png"/>
<BitmapImage x:Key="selectallicon" UriSource="selectall.png"/>
<BitmapImage x:Key="cuticon" UriSource="cut.png"/>
<BitmapImage x:Key="copyicon" UriSource="copy.png"/>
<BitmapImage x:Key="pasteicon" UriSource="paste.png"/>
<BitmapImage x:Key="lefticon" UriSource="leftalign.png"/>
<BitmapImage x:Key="centericon" UriSource="centeralign.png"/>
<BitmapImage x:Key="righticon" UriSource="rightalign.png"/>
<BitmapImage x:Key="boldicon" UriSource="bold.png"/>
<BitmapImage x:Key="italicicon" UriSource="italic.png"/>
<BitmapImage x:Key="underlineicon" UriSource="underline.png"/>
<BitmapImage x:Key="increasefonticon" UriSource="increasefont.png"/>
<BitmapImage x:Key="decreasefonticon" UriSource="decreasefont.png"/>
<BitmapImage x:Key="abouticon" UriSource="about.png"/>
</Window.Resources>
以下代码创建一个 Grid
并将其 CommandBinding
s 添加到其 CommandBindings
集合
<Grid>
<Grid.CommandBindings>
<CommandBinding x:Name="newbinding" Command="ApplicationCommands.New"
CanExecute="newbinding_CanExecute" Executed="newbinding_Executed"/>
<CommandBinding x:Name="openbinding" Command="ApplicationCommands.Open"
CanExecute="openbinding_CanExecute" Executed="openbinding_Executed"/>
<CommandBinding x:Name="savebinding" Command="ApplicationCommands.Save"
CanExecute="savebinding_CanExecute" Executed="savebinding_Executed"/>
<CommandBinding x:Name="exitbinding" Command="local:CustomCommands.Exit"
CanExecute="exitbinding_CanExecute" Executed="exitbinding_Executed"/>
在上面的代码中,CommandBinding
的 Command
属性指定命令为“新建”、“打开”、“保存”和“退出”。CanExecute
事件确定是否可以在指定的命令目标上执行该命令。Executed
事件指定在执行命令时应发生的操作。
值得注意的是,ApplicationCommands
类中没有“退出”命令。作为一种解决方法,我们可以创建一个自定义的“退出”命令,如下所示
public static class CustomCommands
{
static CustomCommands()
{
exitCommand = new RoutedCommand("Exit", typeof(CustomCommands));
}
public static RoutedCommand Exit
{
get
{
return (exitCommand);
}
}
static RoutedCommand exitCommand;
}
要使用我们自定义的退出命令,我们在窗口中添加以下引用
xmlns:local="clr-namespace:RichTextPad"
以下是我们的命令的代码
private void newbinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true; // Allow the command to execute.
}
private void newbinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
TextRange range = new TextRange(richTextBox1.Document.ContentStart,
richTextBox1.Document.ContentEnd); // Get RichTextBox content.
range.Text = ""; // Clear RichTextBox content.
this.Title = "Untitled";
}
private void openbinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void openbinding_Executed(object sender, ExecutedRoutedEventArgs e)
// Code to open existing RTF file.
{
try
{
FileDialog dialog = new OpenFileDialog();
dialog.Filter = "RTF Files (*.rtf)|*.rtf|All Files(*.*)|*.*";
dialog.FilterIndex = 1;
if (dialog.ShowDialog() == true)
{
TextRange range = new TextRange(richTextBox1.Document.ContentStart,
richTextBox1.Document.ContentEnd);
FileStream stream = new FileStream(dialog.FileName, FileMode.Open,
FileAccess.Read, FileShare.None);
range.Load(stream, DataFormats.Rtf);
stream.Close();
this.Title = dialog.FileName;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void savebinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void savebinding_Executed(object sender, ExecutedRoutedEventArgs e)
// Code to save the current file.
{
try
{
FileDialog dialog = new SaveFileDialog();
dialog.Filter = "RTF Files (*.rtf)|*.rtf|All Files(*.*)|*.*";
dialog.FilterIndex = 1;
if (dialog.ShowDialog() == true)
{
TextRange range = new TextRange(richTextBox1.Document.ContentStart,
richTextBox1.Document.ContentEnd);
FileStream stream = new FileStream(dialog.FileName, FileMode.Create,
FileAccess.Write, FileShare.None);
range.Save(stream, DataFormats.Rtf);
stream.Close();
this.Title = dialog.FileName;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void exitbinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void exitbinding_Executed(object sender, ExecutedRoutedEventArgs e)
// Code to exit from the application
{
Application.Current.Shutdown();
}
在上面的函数中,我使用 TextRange
类来获取 RichTextBox
内容并流式输入/输出以打开/保存文件。
以下预定义的命令可用于实现 RichTextBox
控件上的各种文本编辑操作。
<CommandBinding x:Name="undobinding" Command="ApplicationCommands.Undo"/>
<CommandBinding x:Name="redobinding" Command="ApplicationCommands.Redo"/>
<CommandBinding x:Name="selectallbinding" Command="ApplicationCommands.SelectAll"/>
<CommandBinding x:Name="cutbinding" Command="ApplicationCommands.Cut"/>
<CommandBinding x:Name="copybinding" Command="ApplicationCommands.Copy"/>
<CommandBinding x:Name="pastebinding" Command="ApplicationCommands.Paste"/>
<CommandBinding x:Name="leftalignbinding" Command="EditingCommands.AlignLeft"/>
<CommandBinding x:Name="centeralignbinding" Command="EditingCommands.AlignCenter"/>
<CommandBinding x:Name="rightalignbinding" Command="EditingCommands.AlignRight"/>
<CommandBinding x:Name="boldbinding" Command="EditingCommands.ToggleBold"/>
<CommandBinding x:Name="italicbinding" Command="EditingCommands.ToggleItalic"/>
<CommandBinding x:Name="underlinebinding" Command="EditingCommands.ToggleUnderline"/>
<CommandBinding x:Name="increasefontbinding" Command="EditingCommands.IncreaseFontSize"/>
<CommandBinding x:Name="decreasefontbinding" Command="EditingCommands.DecreaseFontSize"/>
以下代码创建工具栏按钮以执行命令
<ToolBarTray Background="White">
<ToolBar Band="1" BandIndex="1" Height="50">
<Button CommandTarget="{Binding richTextBox1}" Command="ApplicationCommands.New" ToolTip="New">
<Image Source="{StaticResource newicon}"/>
</Button>
<Button CommandTarget="{Binding richTextBox1}" Command="ApplicationCommands.Open" ToolTip="Open">
<Image Source="{StaticResource openicon}"/>
</Button>
<Button CommandTarget="{Binding richTextBox1}" Command="ApplicationCommands.Save" ToolTip="Save">
<Image Source="{StaticResource saveicon}"/>
</Button>
<Button CommandTarget="{Binding richTextBox1}" Command="local:CustomCommands.Exit" ToolTip="Exit">
<Image Source="{StaticResource exiticon}"/>
</Button>
</ToolBar>
<ToolBar Band="1" BandIndex="2" Height="50">
<Button Command="ApplicationCommands.Undo" ToolTip="Undo">
<Image Source="{StaticResource undoicon}"/>
</Button>
<Button Command="ApplicationCommands.Redo" ToolTip="Redo">
<Image Source="{StaticResource redoicon}"/>
</Button>
</ToolBar>
<ToolBar Band="1" BandIndex="3" Height="50">
<Button Command="ApplicationCommands.SelectAll" ToolTip="Select All">
<Image Source="{StaticResource selectallicon}"/>
</Button>
<Button Command="ApplicationCommands.Cut" ToolTip="Cut">
<Image Source="{StaticResource cuticon}"/>
</Button>
<Button Command="ApplicationCommands.Copy" ToolTip="Copy">
<Image Source="{StaticResource copyicon}"/>
</Button>
<Button Command="ApplicationCommands.Paste" ToolTip="Paste">
<Image Source="{StaticResource pasteicon}"/>
</Button>
</ToolBar>
<ToolBar Band="1" BandIndex="4" Height="50">
<Button Command="EditingCommands.AlignLeft" ToolTip="Align Left">
<Image Source="{StaticResource lefticon}"/>
</Button>
<Button Command="EditingCommands.AlignCenter" ToolTip="Align Center">
<Image Source="{StaticResource centericon}"/>
</Button>
<Button Command="EditingCommands.AlignRight" ToolTip="Align Right">
<Image Source="{StaticResource righticon}"/>
</Button>
</ToolBar>
<ToolBar Band="2" BandIndex="1" Height="50">
<Button Command="EditingCommands.ToggleBold" ToolTip="Bold">
<Image Source="{StaticResource boldicon}"/>
</Button>
<Button Command="EditingCommands.ToggleItalic" ToolTip="Italic">
<Image Source="{StaticResource italicicon}"/>
</Button>
<Button Command="EditingCommands.ToggleUnderline" ToolTip="Underline">
<Image Source="{StaticResource underlineicon}"/>
</Button>
</ToolBar>
<ToolBar Band="2" BandIndex="2" Height="50">
<ComboBox Name="cbFonts" ItemsSource="{x:Static Fonts.SystemFontFamilies}"
SelectedIndex="0" ToolTip="Font">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontFamily="{Binding}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Button Command="EditingCommands.IncreaseFontSize" ToolTip="Increase Font Size">
<Image Source="{StaticResource increasefonticon}"/>
</Button>
<Button Command="EditingCommands.DecreaseFontSize" ToolTip="Decrease Font Size">
<Image Source="{StaticResource decreasefonticon}"/>
</Button>
</ToolBar>
<ToolBar Band="2" BandIndex="3" Height="50">
<ext:ColorPicker Name="colorChooser"
SelectedColorChanged="colorChooser_SelectedColorChanged" ToolTip="Text Color"/>
</ToolBar>
<ToolBar Band="2" BandIndex="4" Height="50">
<Button Name="btnAbout" ToolTip="About RichTextPad" Click="btnAbout_Click">
<Image Source="{StaticResource abouticon}"/>
</Button>
</ToolBar>
</ToolBarTray>
以下代码用于在选定的文本上设置字体
void cbFonts_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
TextRange range = new TextRange(richTextBox1.Selection.Start,
richTextBox1.Selection.End); // Get RichTextBox content.
range.ApplyPropertyValue(RichTextBox.FontFamilyProperty,
cbFonts.SelectedValue); // Set the font selected from ComboBox on the RichTextBox
}
由于 WPF 中没有颜色选择对话框,我使用了 Extended WPF Toolkit 中的颜色选择器。将 Extended WPF Toolkit 库的引用添加到项目,并添加以下命名空间
xmlns:ext="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended"
颜色选择器控件的添加方式如下
<ext:ColorPicker Name="colorChooser"
SelectedColorChanged="colorChooser_SelectedColorChanged" ToolTip="Text Color"/>
以下代码用于在选定的文本上设置颜色
private void colorChooser_SelectedColorChanged(object sender, RoutedPropertyChangedEventArgs<color> e)
{
// Get RichTextBox content.
TextRange range = new TextRange(richTextBox1.Selection.Start, richTextBox1.Selection.End);
range.ApplyPropertyValue(RichTextBox.ForegroundProperty,
new SolidColorBrush(colorChooser.SelectedColor));
// Apply the selected color.
}</color>
关注点
WPF 提供了一个丰富的编程模型来操作 RichTextBox
。一旦我开始从事这个项目,我就意识到 WPF RichTextBox
控件的许多功能。我希望我的文章能帮助读者在短时间内理解这些概念。