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 还可以包含 Inline 元素。 |
Inline 元素是从 Inline 继承的类。一个 Inline 元素或者包含在一个 Block 元素中,或者包含在另一个 Inline 元素中。 Inline 元素通常用作在屏幕上呈现的内容的直接容器。 例如,一个 Paragraph(Block 元素)可以包含 Run(Inline 元素),但 Run 实际包含在屏幕上呈现的文本。 每个 Paragraph 元素中的内容都可以包含如下许多类型的元素:
Inline 元素 |
描述 |
---|---|
Span 将其他 Inline 内容元素组织到一起。对于 Span 元素中的内容,不应用任何继承呈现。 也就是说,如果将内容放置于 Span 元素内且没有任何属性时,不格式化内容。 但是,从 Span 继承的元素(例如 Hyperlink、Bold、Italic 和 Underline)会向文本应用格式。 |
|
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" Name="Windowa" Closed="MainWindow_OnClosed"> 5 <Grid Margin="0,0,2,0"> 6 <RichTextBox HorizontalAlignment="Left" FontSize="20" BorderBrush="Violet" VerticalScrollBarVisibility="Auto" Height="135" VerticalAlignment="Top" Width="802" Margin="10,374,0,0" Name="SendMessageRichTextBox"> 7 <FlowDocument Name="SendDocument"> 8 <Paragraph Name="SendMessageParas"> 9 <Run></Run> 10 </Paragraph> 11 </FlowDocument> 12 </RichTextBox> 13 <RichTextBox HorizontalAlignment="Left" AllowDrop="True" VerticalScrollBarVisibility="Auto" Height="348" IsReadOnly="True" VerticalAlignment="Top" Width="802" Margin="10,10,0,0" Name="MessageRichTextBox"> 14 <FlowDocument Name="MessageDocument"> 15 </FlowDocument> 16 </RichTextBox> 17 <Button Content="浏览图片" Name="BrowserButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="667,534,0,0" Click="BrowserButton_Click"/> 18 <Button Content="发送" Name="SendButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="752,534,0,0" Click="SendButton_Click"/> 19 20 </Grid> 21 </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 BrowserButton_Click(object sender, RoutedEventArgs e) 2 { 3 try 4 { 5 SendImage(); 6 } 7 catch (Exception) 8 { 9 10 throw; 11 } 12 }
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 = _fileName 14 }; 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 else 23 { 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 //记录Span 6 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 private void SendMessage() 2 { 3 index = 0; 4 //把richtextBox内容转成字符串形式 5 // var strDoc = System.Windows.Markup.XamlWriter.Save(SendMessageRichTextBox.Document); 6 var run = new Run("我:\t" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")) 7 { 8 Foreground = System.Windows.Media.Brushes.Green 9 }; 10 var msg = new Paragraph(run); 11 MessageDocument.Blocks.Add(msg); 12 13 var blockCount = SendDocument.Blocks.Count; 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 } 34 else 35 { 36 p = new Paragraph(); 37 foreach (var item in SendMessageParas.Inlines) 38 { 39 SetData(item); 40 } 41 MessageDocument.Blocks.Add(p); 42 43 } 44 //清理块 45 SendDocument.Blocks.Clear(); 46 SendMessageParas = new Paragraph(new Run("")); 47 SendDocument.Blocks.Add(SendMessageParas); 48 MessageRichTextBox.ScrollToEnd(); 49 }
1 //设置数据 2 private void SetData(Inline item) 3 { 4 if (item is Run) 5 { 6 var text = (item as Run).Text; 7 if(string.IsNullOrWhiteSpace(text))return; 8 var r = new Run(text); 9 p.Inlines.Add(r); 10 MessageDocument.Blocks.Add(p); 11 } 12 else if (item is Span) 13 { 14 var s = item as Span; 15 spans.Add(index, s); 16 parasList.Add(p); index++; 17 } 18 else if (item is InlineUIContainer) 19 { 20 var child = item as InlineUIContainer; 21 var image = child.Child as Image; 22 if (image == null) return; 23 var img = new Image {Source = image.Source, Width = image.Width, Height = image.Height}; 24 p.Inlines.Add(img); 25 MessageDocument.Blocks.Add(p); 26 } 27 else 28 { 29 MessageDocument.Blocks.Add(p); 30 31 } 32 }
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出现,所以会乱,目前还解决不了。额
这是粘贴代码后生成的xml
1 <FlowDocument PagePadding="5,0,5,0" Name="SendDocument" AllowDrop="True" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> 2 <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16"> 3 <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> </Span> 4 <Span Foreground="#FF0000FF" Background="#FFFFFFFF">try</Span> 5 </Paragraph> 6 <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16"> 7 <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> {</Span> 8 </Paragraph> 9 <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16"> 10 <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> SendMessage();</Span> 11 </Paragraph> 12 <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16"> 13 <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> }</Span> 14 </Paragraph> 15 <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16"> 16 <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> </Span> 17 <Span Foreground="#FF0000FF" Background="#FFFFFFFF">catch</Span> 18 <Span Foreground="#FF000000" Background="#FFFFFFFF"> (</Span> 19 <Span Foreground="#FF2B91AF" Background="#FFFFFFFF">Exception</Span> 20 <Span Foreground="#FF000000" Background="#FFFFFFFF">)</Span> 21 </Paragraph> 22 <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16"> 23 <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> {</Span> 24 </Paragraph> 25 <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16"> 26 <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> }</Span> 27 </Paragraph> 28 <Paragraph Name="SendMessageParas" /> 29 </FlowDocument>
所以最后的结果是酱紫的:
7.OK 说完了,补充一点:
.NET技术交流群 199281001 .欢迎加入。
觉得本文对你有所帮助,就点右下角推荐吧,谢谢。