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

运行环境:Win10 x64, NetFrameWork 4.8, 作者:乌龙哈里,日期:2019-05-05


参考:

章节:

  1. 挑选显示数据容器历程
  2. 读取文本到 RichTextBox
  3. 计算第几个字符

一、挑选显示数据容器历程

最近想写一个类似 UltraEdit 查看文件内容,以16进制显示每字节。首先碰到的问题就是下面这个界面:

在 WPF 下尝试了不少方法,同时读一个28k byte 的文件,利弊如下:

方法一:用 Canvas 做容器,一个字节一个 Textbox,写入、修改、变色等操作是很方便,结果载入数据显示的时候要停顿10多秒,而且内存占用达到了1g 以上,同样的文件 UltraEdit 才占用 28m 左右。放弃;

方法二:把 TextBox 换成轻量些的 TextBlock,内存占用达 120m左右,载入数据也比较慢,放弃;

方法三:还用 TextBox ,但是只用显示页面上能摆放的数量,不再一个字节一个,占用才60多兆,但用鼠标滚动翻页时,停顿感很强,不流畅。放弃;

方法三:用 一个字节一个 GlyphRun 直接在 Canvas上画出来,内存占用也很大,比方法二还要大,不明所以,放弃;

方法四:用 一个字节一个 FormattedText 画在 Canvas 上,直接在 Canvas 的 OnRender() 里生成也占用内存 80多兆。不在 OnRender() 里需要把 FormattedText 转化成 FrameworkElement,占用直接上到120多兆。放弃

最后发现用 一个 RichTextBox 来载入数据又快又省,占用内存才28m,和 UltraEdit 相当。(不用单个 TextBox 是因为改动时想标记不同颜色,TextBox 很难做到)。
以后把这些实验的心得也记录下来。

二、读取文本到 RichTextBox

StringBuilder sb = new StringBuilder();
for (int i = 0; i < CntData.Length; i++)//CntData是读取文件的字节数组
{
if (i % NumInLine == 0 && i != 0) //NumInLine=16 每行显示16个字节
{
sb.Append("\r\n");
}
sb.Append(CntData[i].ToString("X2"));
sb.Append(" ");
}
//--TextRange.Text=sb.ToString()方法比下面用 Paragraph 的要慢好多
//TextRange tr = new TextRange(rtbShow.Document.ContentStart, rtbShow.Document.ContentEnd);
//tr.Text = sb.ToString();
Paragraph p = new Paragraph();
p.Inlines.Add(new Run(sb.ToString()));
rtbShow.Document.Blocks.Add(p);//rtbShow RichTextBox 控件的名称
InputMethod.SetIsInputMethodEnabled(rtbShow, false);//关掉输入法
//把输入改成 overwrite 模式
PropertyInfo textEditorProperty = typeof(RichTextBox).GetProperty("TextEditor", BindingFlags.NonPublic | BindingFlags.Instance);
object textEditor = textEditorProperty.GetValue(rtbShow, null);
// set _OvertypeMode on the TextEditor
PropertyInfo overtypeModeProperty = textEditor.GetType().GetProperty("_OvertypeMode", BindingFlags.NonPublic | BindingFlags.Instance);
overtypeModeProperty.SetValue(textEditor, true, null);

三、计算第几个字符

//---计算当前鼠标后一个字符从文档开始字符起算是第几个字符
private int GetCharOffset(RichTextBox rtb)
{
TextPointer start = rtb.CaretPosition;//当前鼠标位置
int n = 0;
TextPointerContext tpc = start.GetPointerContext(LogicalDirection.Backward);
while (tpc!=TextPointerContext.None)
{
if (tpc == TextPointerContext.Text) n++;
start = start.GetPositionAtOffset(-1, LogicalDirection.Backward);//注意是 -1
tpc = start.GetPointerContext(LogicalDirection.Backward);
}
return n-1;//从0起算
}

看了 MS 关于 GetPositionAtOffset() 的解释:
参数
offset
Int32
偏移量(以符号数为单位),使用它计算并返回位置。 如果偏移量为负,则返回的 TextPointer 位于当前 TextPointer 之前;否则,位于它之后。
direction
LogicalDirection
LogicalDirection 值之一,它指定返回的 TextPointer 的逻辑方向。

上面那段程序中只能写-1,要是是 1的话,永远得不到 TextPointerContext.None 。

WPF RichTextBox 当前光标后一个字符是文档的第几个字符的更多相关文章

  1. Word:高亮显示文档中的所有英文字符

     造冰箱的大熊猫,本文适用于Microsoft Office 2007@cnblogs 2019/4/2 文中图片可通过点击鼠标右键查看大图 1.场景 某天在阅读一个中英文混编的Word文档时,希望将 ...

  2. ready是先执行的,load后执行,DOM文档的加载步骤

    在jq中在文档载入完毕后有这几种方式去执行指定函数: $(document).ready(function() { // ...代码... }); //document ready 简写 $(func ...

  3. 【转】刚发现一个linux在线文档库。很好很强大。

    原文网址:http://blog.csdn.net/longxibendi/article/details/6048231 1.网址: http://www.mjmwired.net 2.比如查看这个 ...

  4. 用mkdocs在gitee码云上建立一个简单的文档博客

    利用mkdocs建立简单的文档博客 一.概述 MkDocs 是一个用于创建项目文档的 快速, 简单 , 完美华丽 的静态站点生成器. 文档源码使用 Markdown 来撰写, 用一个 YAML 文件作 ...

  5. Swagger: 一个restful接口文档在线生成+功能测试软件

    一.什么是 Swagger? Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件.Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 ...

  6. [办公自动化]计算机突然死机后asd自动恢复文档未能恢复,如何打开使用

    今天计算机突然死机,但是word未能提示自动恢复窗格.所以无法自动恢复word文档.但是在文档所在的文件夹看到了一个“自动恢复”开头的asd恢复文档. 该如何使用这个文档呢? 按照以前的惯例,尝试了如 ...

  7. aspose words做插入压缩后图片到Word文档中

    最近用aspose words做导出Word的功能,发现图片的导出有点难受,一开始是这样写的 Document doc = new Document("D:\\Template.docx&q ...

  8. tomcat字符,文档,数据库配置

    修改tomcat目录下conf目录下的server.xml tomcat容器的解码配置 URIEncoding="UTF-8" <Connector port="8 ...

  9. 一个最简html5文档来说明html5的新特性和写法

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="utf-8&quo ...

随机推荐

  1. teb教程8

    融合动态障碍物 简介:考虑怎样把其他节点发布的动态障碍物考虑进来 1.本部分演示了动态障碍物该如何被包含到teb_local_planner中. 2.写一个简单的动态障碍物的发布器publish_dy ...

  2. Codeforces 351C Jeff and Brackets 矩阵优化DP

    题意:你要在纸上画一个长度为n * m的括号序列,第i个位置画左括号的花费是a[i % n], 画右括号的花费是b[i % n],问画完这个括号序列的最小花费.n <= 20, m <= ...

  3. Java中实现线程通信的三个方法的作用是什么?

    Java提供了3个方法解决线程之间的通信问题,均是java.lang.Object类的方法,都只能在同步方法或者同步代码块中使用,否则会抛出异常. 方法名 作 用 final void wait() ...

  4. cdq分治(陈丹琦分治)

    //转自:http://blog.csdn.net/snowy_smile/article/details/49668689 /* 算法介绍之cdq分治: 其实cdq分治的思想与应用都能被很简单地描述 ...

  5. 每天一个Linux命令:mkdir(4)

    mkdir mkdir命令 用来创建指定的名称的目录,要求创建目录的用户在当前目录中具有写权限,并且指定的目录名不能是当前目录中已有的目录 格式 mkdir [选项] [目录..] 参数选项 参数 备 ...

  6. Android中怎么破解游戏之修改金币数

    我们在玩游戏的时候总是会遇到一些东东需要进行购买的,但是我们可能又舍不得花钱,那么我们该怎么办呢?那就是用游戏外挂吧!我们这里说的是Android中的游戏,在网上搜索一下移动端游戏外挂,可能会找到一款 ...

  7. SCP-bzoj-1068

    项目编号:bzoj-1068 项目等级:Safe 项目描述: 戳这里 特殊收容措施: 区间DP.f[l][r][s]表示l到r的子串能最小被压成的长度,其中s∈[0,1]表示该串压缩后串中是否能含有M ...

  8. DOM学习总结(四)DOM修改

    DOOM修改 找到标签之后就可以对它进行修改了可以修改:1.改变HTML元素 比如说把 p 改为 span2.改变HTML属性 比如说 id class3.改变CSS样式 比如说改变字体颜色4.添加或 ...

  9. delphi 文件操作(信息获取)

    delphi获取Exe文件版本信息的函数 Type TFileVersionInfo = Record FixedInfo:TVSFixedFileInfo; {版本信息} CompanyName:S ...

  10. 2015ICPC chanchun HDU 5534 (树形题转换完全背包)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5534 题意:给你n个点,让你加上n-1条边使他变成一棵树,题目首先给你a[1] a[2].....a[n- ...