浙江做网站公司,专业创建网站,wordpress 主题转换,智能管理系统定制开发在实际应用中#xff0c;富文本随处可见#xff0c;如留言板#xff0c;聊天软件#xff0c;文档编辑#xff0c;特定格式内容等#xff0c;在WPF开发中#xff0c;如何实现富文本编辑呢#xff1f;本文以一个简单的小例子#xff0c;简述如何通过RichTextBox实现富文…在实际应用中富文本随处可见如留言板聊天软件文档编辑特定格式内容等在WPF开发中如何实现富文本编辑呢本文以一个简单的小例子简述如何通过RichTextBox实现富文本编辑功能主要实现复制剪切粘贴撤销重做保存打开文本加粗斜体下划线删除线左对齐居中对齐右对齐两端对齐缩进减少缩进项目符号数字符号上标下标背景色前景色图片打印等功能仅供学习分享使用如有不足之处还请指正。 什么是RichTextBox 使用RichTextBox可以显示或编辑流内容如文本图片表格等TextBox和RichTextBox都可以用于编辑文本但使用场景不同。如果是单纯的无格式的纯文本建议使用TextBox如果是需要编辑带格式的文本、图像、表格或其他多种格式的内容时RichTextBox 是更好的选择。 什么是流内容和流文档 通常情况下所有在富文本编辑器中呈现的内容都是流内容(FlowContent)而为了呈现流内容的构建块称为流内容元素(Element)。不同的流内容元素组成了流文档(FlowDocument)RichTextBox是流文档的托管对象之一。
流文档旨在根据窗口大小、设备分辨率和其他环境变量来“重排内容”。 此外流文档还具有很多内置功能包括搜索、能够优化可读性的查看模式以及更改字体大小和外观的功能。 当易读性是文档的主要使用要求时最适合使用流文档。 涉及知识点 在通过RichTextBox实现富文本编辑器时涉及到的知识点如下所示
根据流内容的用途可分为两个重要类别 Block 派生类也称为“Block 内容元素”或简称为“Block 元素”。 继承自 Block 的元素可用于将元素分组到一个公用父级下或将公用属性应用于某个组。 Inline 派生类也称为“Inline 内容元素”或简称为“Inline 元素”。 继承自 Inline 的元素要么包含在 Block 元素中要么包含在另一个 Inline 元素中。 Inline 元素通常用作在屏幕上呈现的内容的直接容器。 例如ParagraphBlock 元素可包含 RunInline 元素而 Run 实际包含在屏幕上呈现的文本。
在实现富文本编辑器时需要用到图标实现主要内容如下
在本示例中图标主要通过自定义路径Path实现其中Data属性是Geometry类型用于接收自定以的图形。而用到的图标类型数据可以通过iconfont官网进行获取。在本示例中用到很多图标为了统一管理创建资源字典图标数据作为一种资源引入。
操作流文档时常见使用到的类如下所示 创建RichTextBox RichTextBox托管流文档对象流文档包含流内容包括文本段落图像表格等内容创建语法如下所示
RichTextBox x:NamerichTextBox AcceptsTabTrue Grid.Row1 BorderThickness1 BorderBrushLightBlue Margin2 Padding2 ScrollViewer.CanContentScrollTrue ScrollViewer.VerticalScrollBarVisibilityAutoRichTextBox.DocumentFlowDocumentParagraphI am a sunny boy. My name is xxxx. I am from xxxx Primary School. I am over 1.5 meters old when I just turned 12. Alas, I may be a little fat because of eating too much sugar. A pair of pretty big eyes are inlaid under the dark hair and curved eyebrows. There is also a thin mouth./ParagraphParagraphI like to play computer games. I play online whenever I have time, and my mother scolds me all day. I also like reading. Once, when I went to the library to read, I was fascinated by it. I was immersed in the ocean of knowledge and didnt remember to go home for dinner. I didnt want to leave until the library closed. I also like to play basketball. Every Saturday and Sunday, I will invite some friends to play basketball for a few hours./ParagraphParagraphMy advantage is that I love to move. Every morning I go outside to exercise, run, play the horizontal bar, etc. My math scores are also very good, but my Chinese and English scores are average, so my face is always filled with joy. My shortcoming is that I cant play table tennis, and I dont know what is going on. I just dont like it. This is me. If your hobbies are the same as mine, you can find me./ParagraphParagraphthank you./Paragraph/FlowDocument/RichTextBox.Document
/RichTextBox 编辑命令 为了方便起见WPF 提供由 ApplicationCommands、MediaCommands、ComponentCommands、NavigationCommands 和 EditingCommands 组成的常用命令库你也可以定义自己的命令。在实现富文本编辑器时用到的命令主要有三种
ApplicationCommands主要是应用程序中常见的命令如复制Copy剪切Cut粘贴Paste重做Redo撤销Undo等。EditingCommands 提供了一组常见的编辑相关的命令如加粗Bold斜体Italic下划线UnderLine左对齐右对齐居中对齐两端对齐缩进减少缩进项目符号数字符号等。自定义命令默认RichTextBox并没有提供相应的命令所以需要根据功能自行定义如背景色前景色打印打开保存上标下标图像等。 编辑命令页面布局和绑定 使用WPF自带的命令需要指定Command和CommandTarget两个属性否则将不起作用。其中Command直接使用Commnad命令名称CommandTarget“{Binding ElementName控件名称}”的格式进行绑定。
自定义命令需要通过Command{Binding 命令名称}的格式进行绑定。具体如下所示
StackPanel OrientationHorizontal Grid.Row0Button ToolTip打开 Command{Binding OpenCommand}Path Data{StaticResource icon_open} StretchFill Fill#1296db/Path/ButtonButton ToolTip保存 Command{Binding SaveCommand}Path Data{StaticResource icon_save} StretchFill Fill#1296db/Path/ButtonGridSplitter Width1 Margin3 2 3 2 BackgroundLightGray IsEnabledFalse/GridSplitterButton ToolTip剪切 CommandApplicationCommands.Cut CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_cut} StretchFill FillBlack/Path/ButtonButton ToolTip复制 CommandApplicationCommands.Copy CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_copy} StretchFill Fill#1296db/Path/ButtonButton ToolTip粘贴 CommandApplicationCommands.Paste CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_paste} StretchFill Fill#1296db/Path/ButtonButton ToolTip撤销 CommandApplicationCommands.Undo CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_undo} StretchFill Fill#8a8a8a/Path/ButtonButton ToolTip重做 CommandApplicationCommands.Redo CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_redo} StretchFill Fill#8a8a8a/Path/ButtonGridSplitter Width1 Margin3 2 3 2 BackgroundLightGray IsEnabledFalse/GridSplitterButton ToolTip加粗 CommandEditingCommands.ToggleBold CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_bold} StretchFill FillBlack/Path/ButtonButton ToolTip斜体 CommandEditingCommands.ToggleItalic CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_italic} StretchFill FillLightGray/Path/ButtonButton ToolTip下划线 CommandEditingCommands.ToggleUnderline CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_underline} StretchFill FillGray/Path/ButtonButton ToolTip删除线 Command{Binding SettingCommand} CommandParameterStrikeLinePath Data{StaticResource icon_strikeline} StretchFill FillBlack/Path/ButtonButton ToolTip左对齐 CommandEditingCommands.AlignLeft CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_left} StretchFill FillBlack StrokeLimeGreen/Path/ButtonButton ToolTip居中对齐 CommandEditingCommands.AlignCenter CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_center} StretchFill FillBlack StrokeLimeGreen/Path/ButtonButton ToolTip右对齐 CommandEditingCommands.AlignRight CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_right} StretchFill FillBlack StrokeLimeGreen/Path/ButtonButton ToolTip两端对齐 CommandEditingCommands.AlignJustify CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_justify} StretchFill FillBlack StrokeLimeGreen/Path/ButtonButton ToolTip缩进 CommandEditingCommands.IncreaseIndentation CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_addident} StretchFill FillDimGray/Path/ButtonButton ToolTip减少缩进 CommandEditingCommands.DecreaseIndentation CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_lessident} StretchFill FillDimGray/Path/ButtonButton ToolTip项目编号 CommandEditingCommands.ToggleBullets CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_bullets} StretchFill FillDimGray/Path/ButtonButton ToolTip数字编号 CommandEditingCommands.ToggleNumbering CommandTarget{Binding ElementNamerichTextBox}Path Data{StaticResource icon_numbering} StretchFill FillDimGray/Path/ButtonButton ToolTip上标 Command{Binding SettingCommand} CommandParameterSuperPath Data{StaticResource icon_upper} StretchFill FillCadetBlue/Path/ButtonButton ToolTip下标 Command{Binding SettingCommand} CommandParameterSubPath Data{StaticResource icon_down} StretchFill FillCadetBlue/Path/ButtonGridSplitter Width1 Margin3 2 3 2 BackgroundLightGray IsEnabledFalse/GridSplitterGrid BackgroundWhite Width42 Height30 Margin3ComboBox Width42 Height30 BorderThickness0 HorizontalAlignmentLeft VerticalAlignmentCenter SelectedIndex0 BorderBrushWhite BackgroundWhite NamecombBackgroundComboBoxItem Background#000000 Content#000000/ComboBoxItemComboBoxItem Background#FF0000 Content#FF0000/ComboBoxItemComboBoxItem Background#00FF00 Content#00FF00/ComboBoxItemComboBoxItem Background#0000FF Content#0000FF/ComboBoxItemComboBoxItem Background#00AA00 Content#00AA00/ComboBoxItemComboBoxItem Background#AA0000 Content#AA0000/ComboBoxItemComboBoxItem Background#0000AA Content#0000AA/ComboBoxItemComboBoxItem Background#AA00CC Content#AA00CC/ComboBoxItemComboBoxItem Background#00BBCC Content#00BBCC/ComboBoxItemComboBoxItem Background#555555 Content#555555/ComboBoxItemComboBoxItem Background#AAAAAA Content#AAAAAA/ComboBoxItemComboBoxItem Background#BBBBBB Content#BBBBBB/ComboBoxItemComboBoxItem Background#CCCCCC Content#CCCCCC/ComboBoxItemComboBoxItem Background#DDDDDD Content#DDDDDD/ComboBoxItemComboBoxItem Background#EEEEEE Content#EEEEEE/ComboBoxItemComboBoxItem Background#FFFFFF Content#FFFFFF/ComboBoxItemi:Interaction.Triggersi:EventTrigger EventNameSelectionChangedi:InvokeCommandAction Command{Binding BgColorCommand} CommandParameter{Binding ElementNamecombBackground, PathSelectedItem}//i:EventTrigger/i:Interaction.Triggers/ComboBoxButton ToolTip背景色 Width30 Height30 Padding0 Margin0 HorizontalAlignmentLeft VerticalAlignmentCenterPath Data{StaticResource icon_background} StretchFill Fill{Binding ElementNamecombBackground, PathSelectedItem.Background} /Path/Button/GridGrid BackgroundWhite Width42 Height30 Margin3ComboBox Width42 Height30 BorderThickness0 HorizontalAlignmentLeft VerticalAlignmentCenter SelectedIndex0 BorderBrushWhite BackgroundWhite NamecombForegroundComboBoxItem Background#000000 Content#000000/ComboBoxItemComboBoxItem Background#FF0000 Content#FF0000/ComboBoxItemComboBoxItem Background#00FF00 Content#00FF00/ComboBoxItemComboBoxItem Background#0000FF Content#0000FF/ComboBoxItemComboBoxItem Background#00AA00 Content#00AA00/ComboBoxItemComboBoxItem Background#AA0000 Content#AA0000/ComboBoxItemComboBoxItem Background#0000AA Content#0000AA/ComboBoxItemComboBoxItem Background#AA00CC Content#AA00CC/ComboBoxItemComboBoxItem Background#00BBCC Content#00BBCC/ComboBoxItemComboBoxItem Background#555555 Content#555555/ComboBoxItemComboBoxItem Background#AAAAAA Content#AAAAAA/ComboBoxItemComboBoxItem Background#BBBBBB Content#BBBBBB/ComboBoxItemComboBoxItem Background#CCCCCC Content#CCCCCC/ComboBoxItemComboBoxItem Background#DDDDDD Content#DDDDDD/ComboBoxItemComboBoxItem Background#EEEEEE Content#EEEEEE/ComboBoxItemComboBoxItem Background#FFFFFF Content#FFFFFF/ComboBoxItemi:Interaction.Triggersi:EventTrigger EventNameSelectionChangedi:InvokeCommandAction Command{Binding ForeColorCommand} CommandParameter{Binding ElementNamecombForeground, PathSelectedItem}//i:EventTrigger/i:Interaction.Triggers/ComboBoxButton ToolTip前景色 Width30 Height30 Padding0 Margin0 HorizontalAlignmentLeft VerticalAlignmentCenterPath Data{StaticResource icon_foreground} StretchFill Fill{Binding ElementNamecombForeground, PathSelectedItem.Background} /Path/Button/GridButton ToolTip图像 Command{Binding SettingCommand} CommandParameterImagePath Data{StaticResource icon_img} StretchFill FillGoldenrod/Path/ButtonButton ToolTip打印 Command{Binding SettingCommand} CommandParameterPrintPath Data{StaticResource icon_print} StretchFill FillTomato/Path/Button/StackPanel 自定义命令 在本示例中后台命令使用和属性绑定使用CommunityToolkit.Mvvm库实现。后台实现业务主要分为三种 1. 打开保存命令 打开保存主要实现对RichTextBox中的流文档对象的序列化和反序列化具体如下所示
private IRelayCommand saveCommand;public IRelayCommand SaveCommand
{get{if (saveCommand null){saveCommand new RelayCommand(Save);}return saveCommand;}
}private void Save()
{SaveFileDialog saveFileDialog new SaveFileDialog();saveFileDialog.Title 请选择要保存的路径;saveFileDialog.Filter 富文本格式|*.xaml;bool? flag saveFileDialog.ShowDialog();if (flag true){string _fileNamesaveFileDialog.FileName;TextRange range;FileStream fStream;range new TextRange(this.richTextBox.Document.ContentStart, this.richTextBox.Document.ContentEnd);fStream new FileStream(_fileName, FileMode.Create);range.Save(fStream, DataFormats.XamlPackage);fStream.Close();}
}private IRelayCommand openCommand;public IRelayCommand OpenCommand
{get{if (openCommand null){openCommand new RelayCommand(Open);}return openCommand;}
}private void Open()
{TextRange range;FileStream fStream;OpenFileDialog openFileDialog new OpenFileDialog();openFileDialog.Title 请选择要加载的文件;openFileDialog.Filter 富文本格式|*.xaml;bool? flag openFileDialog.ShowDialog();if (flag true){string _fileName openFileDialog.FileName;if (File.Exists(_fileName)){range new TextRange(this.richTextBox.Document.ContentStart, this.richTextBox.Document.ContentEnd);fStream new FileStream(_fileName, FileMode.OpenOrCreate);range.Load(fStream, DataFormats.XamlPackage);fStream.Close();}}
} 2. 颜色设置命令 颜色设置主要用于将用户选择的颜色赋值给用于选择的流内容元素对象。如下所示
private IRelayCommandobject bgColorCommand;public IRelayCommandobject BgColorCommand
{get{if(bgColorCommand null){bgColorCommand new RelayCommandobject(BgColor);}return bgColorCommand;}
}private void BgColor(object obj)
{if (obj null){return;}var item obj as ComboBoxItem;if (item ! null){var color item.Background;var buttonType Background;SetColor(buttonType, color);}
}private IRelayCommandobject foreColorCommand;public IRelayCommandobject ForeColorCommand
{get{if (foreColorCommand null){foreColorCommand new RelayCommandobject(ForeColor);}return foreColorCommand;}
}private void ForeColor(object obj)
{if (obj null){return;}var item obj as ComboBoxItem;if (item ! null){var color item.Background;var buttonType Foreground;SetColor(buttonType, color);}
}private void SetColor(string buttonType, Brush brush)
{var textSelection this.richTextBox.Selection;if (textSelection null){return;}if (buttonType Background){var propertyValue textSelection.GetPropertyValue(TextElement.BackgroundProperty);var bgBrush (Brush)propertyValue;if (bgBrush brush){textSelection.ApplyPropertyValue(TextElement.BackgroundProperty, Colors.White);}else{textSelection.ApplyPropertyValue(TextElement.BackgroundProperty, brush);}}if (buttonType Foreground){var propertyValue textSelection.GetPropertyValue(TextElement.ForegroundProperty);var foreground (Brush)propertyValue;if (foreground brush){textSelection.ApplyPropertyValue(TextElement.ForegroundProperty, Colors.Black);}else{textSelection.ApplyPropertyValue(TextElement.ForegroundProperty, brush);}}
} 3. 其他设置命令 其他设置命令如删除线上标下标图像插入打印等命令如下所示
private IRelayCommandstring settingCommand;public IRelayCommandstring SettingCommand
{get{if(settingCommand null){settingCommand new RelayCommandstring(Setting);}return settingCommand;}
}private void Setting(string buttonType)
{var textSelection this.richTextBox.Selection;if (textSelection null){return;}if (buttonType StrikeLine){var propertyValue textSelection.GetPropertyValue(Inline.TextDecorationsProperty);var textDecorationCollection (TextDecorationCollection)propertyValue;if (textDecorationCollection TextDecorations.Strikethrough){textSelection.ApplyPropertyValue(Inline.TextDecorationsProperty, null);}else{textSelection.ApplyPropertyValue(Inline.TextDecorationsProperty, TextDecorations.Strikethrough);}}else if (buttonType Super){var propertyValue textSelection.GetPropertyValue(Inline.BaselineAlignmentProperty);var supper (BaselineAlignment)propertyValue;if (supper BaselineAlignment.Superscript){textSelection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Top);}else{textSelection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Superscript);}}else if(buttonType Sub){var propertyValue textSelection.GetPropertyValue(Inline.BaselineAlignmentProperty);var sub (BaselineAlignment)propertyValue;if (sub BaselineAlignment.Subscript){textSelection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Top);}else{textSelection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Subscript);}}else if (buttonType Image){OpenFileDialog openFileDialog new OpenFileDialog();openFileDialog.Title 请选择需要插入的图片;openFileDialog.Filter 图片文件|*.png;bool? flag openFileDialog.ShowDialog();if (flag true){var fileName openFileDialog.FileName;var img new Image() { Source new BitmapImage(new Uri(fileName)), Stretch Stretch.Uniform, Width this.richTextBox.ActualWidth - 50 };var imgContainer new BlockUIContainer(img);this.richTextBox.CaretPosition.InsertParagraphBreak();this.richTextBox.Document.Blocks.InsertBefore(this.richTextBox.CaretPosition.Paragraph, imgContainer);}}else if(buttonType Print){PrintDialog pd new PrintDialog();if ((pd.ShowDialog() true)){//use either one of the belowpd.PrintVisual(this.richTextBox as Visual, 打印富文本1);pd.PrintDocument((((IDocumentPaginatorSource)this.richTextBox.Document).DocumentPaginator), 打印富文本2);}}
} 示例截图 主要实现复制剪切粘贴撤销重做保存打开文本加粗斜体下划线删除线左对齐居中对齐右对齐两端对齐缩进减少缩进项目符号数字符号上标下标背景色前景色图片打印等功能效果如下 源码下载 关于源码下载可关注公众号回复WPFRICH进行下载如下所示 参考文献 流文档介绍https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/advanced/flow-document-overview?viewnetframeworkdesktop-4.8
RichTextBox介绍https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/controls/richtextbox-overview?viewnetframeworkdesktop-4.8
ApplicationCommands介绍https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.input.applicationcommands?viewwindowsdesktop-8.0
EditingCommands介绍https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.documents.editingcommands?viewwindowsdesktop-8.0
以上就是【浅谈WPF之利用RichTextBox实现富文本编辑器】的全部内容。