首页 > 代码库 > WPF RichTextBox的使用总结
WPF RichTextBox的使用总结
RichTextBox 支持基于块的内容模型。 RichTextBox 的内容属性为 Blocks,这是 Paragraph 元素的集合Paragraph元素可包含从 Inline 派生的元素。上图总结了 RichTextBox 的内容模型,并且显示从 Block 和 Inline 派生的元素是如何适应此模型的。
1.RichTextBox 是一个可支持您显示或编辑丰富内容(包括段落、超链接和内联图像)的控件。本主题介绍 RichTextBox 控件,描述该控件的一些功能,并且显示如何在 XAML 和代码中使用该控件的一些示例。
2.RichTextBox 分为块和行
3.本人部分文章来源MSDN,原文地址:http://msdn.microsoft.com/zh-cn/library/ee681613(v=vs.95).aspx
Block 元素是从 Block 继承的类。目前,Paragraph 和 Section 从 Block 派生,但 Section 不是 RichTextBox 的文档模型的一部分。
Block 元素 | 描述 |
---|---|
Paragraph | Paragraph 用于将内容分组到一个段落中。 Paragraph 的最简单且最常见的用途是创建文本段落。 Paragraph 还可以包含 Inline 元素。 |
Inline 元素是从 Inline 继承的类。一个 Inline 元素或者包含在一个 Block 元素中,或者包含在另一个 Inline 元素中。 Inline 元素通常用作在屏幕上呈现的内容的直接容器。 例如,一个 Paragraph(Block 元素)可以包含 Run(Inline 元素),但 Run 实际包含在屏幕上呈现的文本。 每个 Paragraph 元素中的内容都可以包含如下许多类型的元素:
Inline 元素 | 描述 |
---|---|
Run | Run 用于包含无格式文本。您可能预期 Run 对象会在内容中广泛使用,不过,在标记中不需要显式使用 Run 元素。 |
Span | Span 将其他 Inline 内容元素组织到一起。对于 Span 元素中的内容,不应用任何继承呈现。 也就是说,如果将内容放置于 Span 元素内且没有任何属性时,不格式化内容。 但是,从 Span 继承的元素(例如 Hyperlink、Bold、Italic 和 Underline)会向文本应用格式。 |
InlineUIContainer | InlineUIContainer 使 UIElement 元素(例如 Image 或 Button 控件)能够嵌入到 Inline 内容元素中。 |
RichTextBox 支持超链接。您可以使用 Hyperlink 元素在 RichTextBox 中显示超链接。 超链接提供内置的鼠标悬停行为和焦点支持。 使用 Hyperlink 元素的 NavigateUri 属性指定 URL。
说明: |
---|
您必须将 RichTextBox 的 IsReadOnly 属性设置为 true,才能使 Hyperlink 元素生效。 |
直接上代码:
1.xaml 代码
1 <Window x:Class="RichTextBoxDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="RichTextBoxDemo" Height="605.108" Width="846.839" Closed="MainWindow_OnClosed"> 5 <Grid Margin="0,0,2,0"> 6 <RichTextBox HorizontalAlignment="Left" AllowDrop="True" VerticalScrollBarVisibility="Auto" Height="135" VerticalAlignment="Top" Width="802" Margin="10,374,0,0" Name="SendMessageRichTextBox"> 7 <FlowDocument Name="SendDocument"> 8 <Paragraph Name="SendMessageParas"></Paragraph> 9 </FlowDocument>10 </RichTextBox>11 <RichTextBox HorizontalAlignment="Left" AllowDrop="True" VerticalScrollBarVisibility="Auto" Height="348" IsReadOnly="True" VerticalAlignment="Top" Width="802" Margin="10,10,0,0" Name="MessageRichTextBox">12 <FlowDocument Name="MessageDocument">13 </FlowDocument>14 </RichTextBox>15 <Button Content="浏览图片" Name="BrowserButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="667,534,0,0" Click="BrowserButton_Click"/>16 <Button Content="发送" Name="SendButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="752,534,0,0" Click="SendButton_Click"/>17 18 </Grid>19 </Window>
2.点击发送按钮
1 private void SendButton_Click(object sender, RoutedEventArgs e) 2 { 3 try 4 { 5 SendMessage(); 6 } 7 catch (Exception) 8 { 9 }10 }
3.选择图片
1 private void SendImage() 2 { 3 //选择图片 4 var dialog = new OpenFileDialog(); 5 dialog.Filter = ".jpg|*.jpg|.png|*.png|.jpeg|*.jpeg"; 6 if (dialog.ShowDialog(this) == false) return; 7 _fileName = dialog.FileName; 8 var a = new Image 9 {10 Source = new BitmapImage(new Uri(_fileName, UriKind.RelativeOrAbsolute)),11 Width = 60,12 Height = 60,13 Tag = _fileName14 };15 var blockCount = SendDocument.Blocks.Count(b => b != null);16 if (blockCount > 1)17 {18 var p = new Paragraph();19 p.Inlines.Add(a);20 SendDocument.Blocks.Add(p);21 }22 else23 {24 SendMessageParas.Inlines.Add(a);25 }26 SendMessageRichTextBox.Focus();27 //将光标至于所有发送框末尾28 SendMessageRichTextBox.CaretPosition = SendDocument.Blocks.LastBlock.ContentEnd;29 }
4.封装的函数和变量
1 #region 变量区域2 //选择图片的文件名3 private string _fileName = string.Empty;4 private Paragraph p = null;5 //记录Span6 Dictionary<int, Span> spans = new Dictionary<int, Span>(0);7 List<Paragraph> parasList = new List<Paragraph>(0);8 private int index = 0;9 #endregion
1 #region 发送消息 2 private void SendMessage() 3 { 4 index = 0; 5 //把richtextBox内容转成字符串形式 6 //string strDoc = System.Windows.Markup.XamlWriter.Save(SendMessageRichTextBox.Document); 7 //上面的逆操作 8 var run = new Run("我:\t" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); 9 run.Foreground = System.Windows.Media.Brushes.RoyalBlue;10 var msg = new Paragraph(run);11 MessageDocument.Blocks.Add(msg);12 13 var blockCount = SendDocument.Blocks.Count(a => a != null);14 //以块的形式发送15 if (blockCount > 1)16 {17 foreach (var item in SendDocument.Blocks.OfType<Paragraph>().SelectMany(b => b.Inlines))18 {19 p = new Paragraph();20 SetData(item);21 22 }23 foreach (var key in spans.Keys)24 {25 var span = spans[key];26 var par = parasList[key];27 par.Inlines.Add(span);28 MessageDocument.Blocks.Add(par);29 }30 spans.Clear();31 parasList.Clear();32 //清理块33 SendDocument.Blocks.Clear();34 SendMessageParas = new Paragraph();35 SendDocument.Blocks.Add(SendMessageParas);36 }37 else38 {39 p = new Paragraph();40 foreach (var item in SendMessageParas.Inlines)41 {42 SetData(item);43 }44 MessageDocument.Blocks.Add(p);45 //清理行46 SendMessageParas.Inlines.Clear();47 }48 49 MessageRichTextBox.ScrollToEnd();50 } 51 #endregion52 53 #region 设置数据54 //设置数据55 private void SetData(Inline item)56 {57 if (item is Run)58 {59 var r = new Run((item as Run).Text);60 p.Inlines.Add(r);61 MessageDocument.Blocks.Add(p);62 }63 else if (item is Span)64 {65 var s = item as Span;66 spans.Add(index, s);67 parasList.Add(p);68 }69 else if (item is InlineUIContainer)70 {71 var child = item as InlineUIContainer;72 var image = child.Child as Image;73 if (image == null) return;74 var img = new Image { Source = image.Source, Width = image.Width, Height = image.Height };75 p.Inlines.Add(img);76 MessageDocument.Blocks.Add(p);77 }78 79 index++;80 }81 #endregion
5.释放资源
1 private void MainWindow_OnClosed(object sender, EventArgs e)2 {3 p = null;4 SendMessageRichTextBox = null;5 MessageRichTextBox = null;6 _fileName = null;7 8 }
6.运行效果图展示:
(1) 普通的发送图片和文本
(2)支持复制,可全选,RichTextBox 原有的,不是我实现的。
(3) 粘贴代码发送和显示,不过这里有问题,带有样式的代码默认都是以Span出现,所以会乱,目前还解决不了,希望大神指教。
7.OK 说完了,补充一点:
.NET技术交流群 199281001 .欢迎加入。
觉得本文对你有所帮助,就点右下角推荐吧,谢谢。