RichTextBox内容模型

RichTextBox 支持基于块的内容模型。 RichTextBox   的内容属性为 Blocks,这是 Paragraph 元素的集合Paragraph元素可包含从 Inline 派生的元素。上图总结了 RichTextBox 的内容模型,并且显示从 BlockInline 派生的元素是如何适应此模型的。

简单介绍

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

2.RichTextBox    分为块和行

3.本文部分文章来源MSDN,原文地址:http://msdn.microsoft.com/zh-cn/library/ee681613(v=vs.95).aspx

Block 元素

Block 元素是从 Block 继承的类。目前,ParagraphSectionBlock 派生,但 Section 不是 RichTextBox 的文档模型的一部分。

Block 元素

描述

Paragraph

Paragraph   用于将内容分组到一个段落中。                         Paragraph   的最简单且最常见的用途是创建文本段落。  Paragraph   还可以包含 Inline 元素。

Inline 元素

Inline 元素是从 Inline 继承的类。一个 Inline 元素或者包含在一个 Block 元素中,或者包含在另一个 Inline 元素中。                 Inline 元素通常用作在屏幕上呈现的内容的直接容器。  例如,一个 Paragraph(Block 元素)可以包含 Run(Inline 元素),但 Run 实际包含在屏幕上呈现的文本。  每个 Paragraph 元素中的内容都可以包含如下许多类型的元素:

 

Inline 元素

描述

Run

Run   用于包含无格式文本。您可能预期 Run 对象会在内容中广泛使用,不过,在标记中不需要显式使用 Run 元素。

Span

Span   将其他 Inline 内容元素组织到一起。对于 Span 元素中的内容,不应用任何继承呈现。  也就是说,如果将内容放置于 Span 元素内且没有任何属性时,不格式化内容。  但是,从 Span 继承的元素(例如 HyperlinkBoldItalicUnderline)会向文本应用格式。

InlineUIContainer

InlineUIContainer   使 UIElement 元素(例如 ImageButton 控件)能够嵌入到 Inline 内容元素中。

 RichTextBox   支持超链接。您可以使用 Hyperlink 元素在 RichTextBox 中显示超链接。  超链接提供内置的鼠标悬停行为和焦点支持。  使用 Hyperlink 元素的 NavigateUri 属性指定 URL。

                   说明:                

您必须将 RichTextBoxIsReadOnly 属性设置为 true,才能使 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 = ,
  12. Height = ,
  13. Tag = _fileName
  14. };
  15. var blockCount = SendDocument.Blocks.Count(b => b != null);
  16. if (blockCount > )
  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>();
  7. List<Paragraph> parasList = new List<Paragraph>();
  8. private int index = ;
  9. #endregion

发送消息函数

  1. private void SendMessage()
  2. {
  3. index = ;
  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 > )
  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 .欢迎加入。

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

WPF RichTextBox的使用总结的更多相关文章

  1. WPF RichTextBox自动调整高度

    原文:WPF RichTextBox自动调整高度 大概两年前的这个时间段,当时做项目遇到了一个问题:环境VS2005.WinForm,需要RichTextBox根据内容自动调整高度.当时用了各种方法都 ...

  2. WPF RichTextBox 禁止换行

    原文:WPF RichTextBox 禁止换行 这个问题困扰了好久,进过不断的努力,终于解决了           <RichTextBox Margin="0,44,10,0&quo ...

  3. WPF RichTextBox 当前光标后一个字符是文档的第几个字符

    WPF RichTextBox 当前光标后一个字符是文档的第几个字符 运行环境:Win10 x64, NetFrameWork 4.8, 作者:乌龙哈里,日期:2019-05-05 参考: TextP ...

  4. WPF RichTextBox读取存储文本的方法和常用属性

    1. 取得已被选中的内容: (1)使用 RichTextBox.Document.Selection属性(2)访问RichTextBox.Document.Blocks属性的“blocks”中的Tex ...

  5. WPF RichTextBox 控件常用方法和属性

    以下内容转自 http://blog.csdn.net/yulongguiziyao/article/details/25330551. 1. 取得已被选中的内容: (1)使用 RichTextBox ...

  6. WPF RichTextBox相关总结

    由于公司涉及到聊天对话框的功能,就想到了RichTextBox,查阅相关资料,总结下: 一.RichTextBox的内容相关的类 1.1RichTextBox的内容结构 RichTexBox是个可编辑 ...

  7. WPF RichTextBox 做内容展示框 滚动条控制判定是否阅读完成

    一.项目背景: 最近,做项目,因为是金融项目,客户登录交易的时候,有一个提示框,就是告知客户要“入市需谨慎”等等,想必大家都遇到这样的场景,当然,这种提示是没人会看的,不过作为交易所,这样的提示又必不 ...

  8. WPF RichTextbox

    WPFTextBoxAutoComplete AvalonEdit WPF SyntaxHighlightBox   WinForm 下的 Fast Colored TextBox for Synta ...

  9. WPF RichTextBox,关键字搜索,样式改变,超链接替换,图文混排

    RichTextBox 只是一个控件,表示对 FlowDocument 对象执行操作的丰富编辑控件.它所承载的内容由其 Document 属性来呈现. Document 是一个 FlowDocumen ...

随机推荐

  1. Ta-lib 函数一览

    import tkinter as tk from tkinter import ttk import matplotlib.pyplot as plt import numpy as np impo ...

  2. Qt——正则表达式

    在项目中经常会遇到对字符串进行操作的情况,我们可以直接使用QString的一些函数,但QT提供了一个更加强大的类——QRegExp,使用正则表达式来操作字符串. 先说说我最近遇到的几个问题: 1.对输 ...

  3. [vim]的关键字补全

    除了complete关键字补全,所有补全相关命令都以CTRL-X开始,然后再接与补全类型相关的命令.CTRL-N与CTRL-P在找的的内容中选择的通用的命令,上下选择用的,CTRL-E则是取消选择.( ...

  4. [CareerCup] 10.5 Web Crawler 网络爬虫

    10.5 If you were designing a web crawler, how would you avoid getting into infinite loops? 这道题问如果让我们 ...

  5. iOS:实现图片的无限轮播之使用第三方库SDCycleScrollView

    下载链接:github不断更新地址:https://github.com/gsdios/SDCycleScrollView #import "ViewController.h" # ...

  6. 20145222黄亚奇《Java程序设计》课程总结

    20145222黄亚奇<JAVA程序设计>课程总结 每周读书笔记链接汇总 第一周读书笔记 第二周读书笔记 第三周读书笔记 第四周读书笔记 第五周读书笔记 第六周读书笔记 第七周读书笔记 第 ...

  7. Scala学习笔记(七):Application特质

    Scala提供了特质scala.Application 在单例对象名后面写上“extends Application”,把想要执行的代码直接放在单例对象的花括号之间 import ChecksumAc ...

  8. [转]Oracle中的索引详解

    原文地址:http://www.oschina.net/question/30362_4057 一. ROWID的概念 存储了row在数据文件中的具体位置:64位 编码的数据,A-Z, a-z, 0- ...

  9. 5.9-4用字符串生成器给字符串str追加1~10这10个数字

    package zfc; public class ZfcShcq { public static void main(String[] args) { // TODO Auto-generated ...

  10. iOS边练边学--多线程介绍、NSThread的简单实用、线程安全以及线程之间的通信

    一.iOS中的多线程 多线程的原理(之前多线程这块没好好学,之前对多线程的理解也是错误的,这里更正,好好学习这块) iOS中多线程的实现方案有以下几种 二.NSThread线程类的简单实用(直接上代码 ...