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 代码
- <Window x:Class="RichTextBoxDemo.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="RichTextBoxDemo" Height="605.108" Width="846.839" Name="Windowa" Closed="MainWindow_OnClosed">
- <Grid Margin="0,0,2,0">
- <RichTextBox HorizontalAlignment="Left" FontSize="20" BorderBrush="Violet" VerticalScrollBarVisibility="Auto" Height="135" VerticalAlignment="Top" Width="802" Margin="10,374,0,0" Name="SendMessageRichTextBox">
- <FlowDocument Name="SendDocument">
- <Paragraph Name="SendMessageParas">
- <Run></Run>
- </Paragraph>
- </FlowDocument>
- </RichTextBox>
- <RichTextBox HorizontalAlignment="Left" AllowDrop="True" VerticalScrollBarVisibility="Auto" Height="348" IsReadOnly="True" VerticalAlignment="Top" Width="802" Margin="10,10,0,0" Name="MessageRichTextBox">
- <FlowDocument Name="MessageDocument">
- </FlowDocument>
- </RichTextBox>
- <Button Content="浏览图片" Name="BrowserButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="667,534,0,0" Click="BrowserButton_Click"/>
- <Button Content="发送" Name="SendButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="752,534,0,0" Click="SendButton_Click"/>
- </Grid>
- </Window>
2.点击发送按钮
- private void SendButton_Click(object sender, RoutedEventArgs e)
- {
- try
- {
- SendMessage();
- }
- catch (Exception)
- {
- }
- }
3.选择图片
- private void BrowserButton_Click(object sender, RoutedEventArgs e)
- {
- try
- {
- SendImage();
- }
- catch (Exception)
- {
- throw;
- }
- }
- private void SendImage()
- {
- //选择图片
- var dialog = new OpenFileDialog();
- dialog.Filter = ".jpg|*.jpg|.png|*.png|.jpeg|*.jpeg";
- if (dialog.ShowDialog(this) == false) return;
- _fileName = dialog.FileName;
- var a = new Image
- {
- Source = new BitmapImage(new Uri(_fileName, UriKind.RelativeOrAbsolute)),
- Width = ,
- Height = ,
- Tag = _fileName
- };
- var blockCount = SendDocument.Blocks.Count(b => b != null);
- if (blockCount > )
- {
- var p = new Paragraph();
- p.Inlines.Add(a);
- SendDocument.Blocks.Add(p);
- }
- else
- {
- SendMessageParas.Inlines.Add(a);
- }
- SendMessageRichTextBox.Focus();
- //将光标至于所有发送框末尾
- SendMessageRichTextBox.CaretPosition = SendDocument.Blocks.LastBlock.ContentEnd;
- }
4.封装的函数和变量
- #region 变量区域
- //选择图片的文件名
- private string _fileName = string.Empty;
- private Paragraph p = null;
- //记录Span
- Dictionary<int, Span> spans = new Dictionary<int, Span>();
- List<Paragraph> parasList = new List<Paragraph>();
- private int index = ;
- #endregion
发送消息函数
- private void SendMessage()
- {
- index = ;
- //把richtextBox内容转成字符串形式
- // var strDoc = System.Windows.Markup.XamlWriter.Save(SendMessageRichTextBox.Document);
- var run = new Run("我:\t" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
- {
- Foreground = System.Windows.Media.Brushes.Green
- };
- var msg = new Paragraph(run);
- MessageDocument.Blocks.Add(msg);
- var blockCount = SendDocument.Blocks.Count;
- //以块的形式发送
- if (blockCount > )
- {
- foreach (var item in SendDocument.Blocks.OfType<Paragraph>().SelectMany(b => b.Inlines))
- {
- p = new Paragraph();
- SetData(item);
- }
- foreach (var key in spans.Keys)
- {
- var span = spans[key];
- var par = parasList[key];
- par.Inlines.Add(span);
- MessageDocument.Blocks.Add(par);
- }
- spans.Clear();
- parasList.Clear();
- }
- else
- {
- p = new Paragraph();
- foreach (var item in SendMessageParas.Inlines)
- {
- SetData(item);
- }
- MessageDocument.Blocks.Add(p);
- }
- //清理块
- SendDocument.Blocks.Clear();
- SendMessageParas = new Paragraph(new Run(""));
- SendDocument.Blocks.Add(SendMessageParas);
- MessageRichTextBox.ScrollToEnd();
- }
- //设置数据
- private void SetData(Inline item)
- {
- if (item is Run)
- {
- var text = (item as Run).Text;
- if(string.IsNullOrWhiteSpace(text))return;
- var r = new Run(text);
- p.Inlines.Add(r);
- MessageDocument.Blocks.Add(p);
- }
- else if (item is Span)
- {
- var s = item as Span;
- spans.Add(index, s);
- parasList.Add(p); index++;
- }
- else if (item is InlineUIContainer)
- {
- var child = item as InlineUIContainer;
- var image = child.Child as Image;
- if (image == null) return;
- var img = new Image {Source = image.Source, Width = image.Width, Height = image.Height};
- p.Inlines.Add(img);
- MessageDocument.Blocks.Add(p);
- }
- else
- {
- MessageDocument.Blocks.Add(p);
- }
- }
5.释放资源
- private void MainWindow_OnClosed(object sender, EventArgs e)
- {
- p = null;
- SendMessageRichTextBox = null;
- MessageRichTextBox = null;
- _fileName = null;
- }
6.运行效果图展示:
(1) 普通的发送图片和文本
(2)支持复制,可全选,RichTextBox 原有的,不是我实现的。
(3) 粘贴代码发送和显示,不过这里有问题,带有样式的代码默认都是以Span出现,所以会乱,目前还解决不了。额
这是粘贴代码后生成的xml
- <FlowDocument PagePadding="5,0,5,0" Name="SendDocument" AllowDrop="True" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
- <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16">
- <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> </Span>
- <Span Foreground="#FF0000FF" Background="#FFFFFFFF">try</Span>
- </Paragraph>
- <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16">
- <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> {</Span>
- </Paragraph>
- <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16">
- <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> SendMessage();</Span>
- </Paragraph>
- <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16">
- <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> }</Span>
- </Paragraph>
- <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16">
- <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> </Span>
- <Span Foreground="#FF0000FF" Background="#FFFFFFFF">catch</Span>
- <Span Foreground="#FF000000" Background="#FFFFFFFF"> (</Span>
- <Span Foreground="#FF2B91AF" Background="#FFFFFFFF">Exception</Span>
- <Span Foreground="#FF000000" Background="#FFFFFFFF">)</Span>
- </Paragraph>
- <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16">
- <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> {</Span>
- </Paragraph>
- <Paragraph Margin="0,0,0,0" FontFamily="Microsoft YaHei" FontSize="16">
- <Span Foreground="#FF000000" Background="#FFFFFFFF" xml:space="preserve"> }</Span>
- </Paragraph>
- <Paragraph Name="SendMessageParas" />
- </FlowDocument>
所以最后的结果是酱紫的:
7.OK 说完了,补充一点:
.NET技术交流群 199281001 .欢迎加入。
觉得本文对你有所帮助,就点右下角推荐吧,谢谢。
WPF RichTextBox的使用总结的更多相关文章
- WPF RichTextBox自动调整高度
原文:WPF RichTextBox自动调整高度 大概两年前的这个时间段,当时做项目遇到了一个问题:环境VS2005.WinForm,需要RichTextBox根据内容自动调整高度.当时用了各种方法都 ...
- WPF RichTextBox 禁止换行
原文:WPF RichTextBox 禁止换行 这个问题困扰了好久,进过不断的努力,终于解决了 <RichTextBox Margin="0,44,10,0&quo ...
- WPF RichTextBox 当前光标后一个字符是文档的第几个字符
WPF RichTextBox 当前光标后一个字符是文档的第几个字符 运行环境:Win10 x64, NetFrameWork 4.8, 作者:乌龙哈里,日期:2019-05-05 参考: TextP ...
- WPF RichTextBox读取存储文本的方法和常用属性
1. 取得已被选中的内容: (1)使用 RichTextBox.Document.Selection属性(2)访问RichTextBox.Document.Blocks属性的“blocks”中的Tex ...
- WPF RichTextBox 控件常用方法和属性
以下内容转自 http://blog.csdn.net/yulongguiziyao/article/details/25330551. 1. 取得已被选中的内容: (1)使用 RichTextBox ...
- WPF RichTextBox相关总结
由于公司涉及到聊天对话框的功能,就想到了RichTextBox,查阅相关资料,总结下: 一.RichTextBox的内容相关的类 1.1RichTextBox的内容结构 RichTexBox是个可编辑 ...
- WPF RichTextBox 做内容展示框 滚动条控制判定是否阅读完成
一.项目背景: 最近,做项目,因为是金融项目,客户登录交易的时候,有一个提示框,就是告知客户要“入市需谨慎”等等,想必大家都遇到这样的场景,当然,这种提示是没人会看的,不过作为交易所,这样的提示又必不 ...
- WPF RichTextbox
WPFTextBoxAutoComplete AvalonEdit WPF SyntaxHighlightBox WinForm 下的 Fast Colored TextBox for Synta ...
- WPF RichTextBox,关键字搜索,样式改变,超链接替换,图文混排
RichTextBox 只是一个控件,表示对 FlowDocument 对象执行操作的丰富编辑控件.它所承载的内容由其 Document 属性来呈现. Document 是一个 FlowDocumen ...
随机推荐
- Ta-lib 函数一览
import tkinter as tk from tkinter import ttk import matplotlib.pyplot as plt import numpy as np impo ...
- Qt——正则表达式
在项目中经常会遇到对字符串进行操作的情况,我们可以直接使用QString的一些函数,但QT提供了一个更加强大的类——QRegExp,使用正则表达式来操作字符串. 先说说我最近遇到的几个问题: 1.对输 ...
- [vim]的关键字补全
除了complete关键字补全,所有补全相关命令都以CTRL-X开始,然后再接与补全类型相关的命令.CTRL-N与CTRL-P在找的的内容中选择的通用的命令,上下选择用的,CTRL-E则是取消选择.( ...
- [CareerCup] 10.5 Web Crawler 网络爬虫
10.5 If you were designing a web crawler, how would you avoid getting into infinite loops? 这道题问如果让我们 ...
- iOS:实现图片的无限轮播之使用第三方库SDCycleScrollView
下载链接:github不断更新地址:https://github.com/gsdios/SDCycleScrollView #import "ViewController.h" # ...
- 20145222黄亚奇《Java程序设计》课程总结
20145222黄亚奇<JAVA程序设计>课程总结 每周读书笔记链接汇总 第一周读书笔记 第二周读书笔记 第三周读书笔记 第四周读书笔记 第五周读书笔记 第六周读书笔记 第七周读书笔记 第 ...
- Scala学习笔记(七):Application特质
Scala提供了特质scala.Application 在单例对象名后面写上“extends Application”,把想要执行的代码直接放在单例对象的花括号之间 import ChecksumAc ...
- [转]Oracle中的索引详解
原文地址:http://www.oschina.net/question/30362_4057 一. ROWID的概念 存储了row在数据文件中的具体位置:64位 编码的数据,A-Z, a-z, 0- ...
- 5.9-4用字符串生成器给字符串str追加1~10这10个数字
package zfc; public class ZfcShcq { public static void main(String[] args) { // TODO Auto-generated ...
- iOS边练边学--多线程介绍、NSThread的简单实用、线程安全以及线程之间的通信
一.iOS中的多线程 多线程的原理(之前多线程这块没好好学,之前对多线程的理解也是错误的,这里更正,好好学习这块) iOS中多线程的实现方案有以下几种 二.NSThread线程类的简单实用(直接上代码 ...