RichTextBox内容模型

WPF RichTextBox的使用总结 

 

RichTextBox 支持基于块的内容模型。 Inline 派生的元素是如何适应此模型的。

 

简单介绍

1.RichTextBox    是一个可支持您显示或编辑丰富内容(包括段落、超链接和内联图像)的控件。RichTextBox 控件,描述该控件的一些功能,并且显示如何在 XAML 和代码中使用该控件的一些示例。

2.RichTextBox    分为块和行

http://msdn.microsoft.com/zh-cn/library/ee681613(v=vs.95).aspx

Block 元素

RichTextBox 的文档模型的一部分。

Block 元素                                           

描述                                           

Paragraph                                           

Paragraph   还可以包含 Inline 元素。

 

Inline 元素

 Inline 元素是从 Inline 继承的类。一个 Inline 元素或者包含在一个 Block 元素中,或者包含在另一个 Inline 元素中。                 Paragraph 元素中的内容都可以包含如下许多类型的元素: 

 

Inline 元素                                           

描述                                           

Run                                           

Run 元素。 

Span                                           

Underline)会向文本应用格式。 

InlineUIContainer                                           

Inline 内容元素中。                      

        

NavigateUri 属性指定 URL。 

                   说明:                

Hyperlink 元素生效。

 RichTextBox案例源码(可发送图片和文字)

 

 直接上代码:

 

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) 普通的发送图片和文本

WPF RichTextBox的使用总结



(2)支持复制,可全选,RichTextBox 原有的,不是我实现的。

WPF 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>

 

所以最后的结果是酱紫的:

 WPF RichTextBox的使用总结

 

 

 7.OK  说完了,补充一点:

 .NET技术交流群 199281001 .欢迎加入。

 觉得本文对你有所帮助,就点右下角推荐吧,谢谢。

 

相关文章: