在使用 RichTextBox 创建自定义编辑器时,我遇到了使用 TextChanged 事件查找已删除/插入的文本的问题。
TextChangedEventArgs的实例有一些有用的数据,但我想它并没有涵盖所有的需求。假设一个场景,插入了多个段落,同时,所选文本(本身跨越多个段落)已被删除。
使用 TextChangedEventArgs 的实例,您有一个文本更改的集合,每个更改只为您提供删除或添加的符号数量及其位置。
我想到的唯一解决方案是保留一份文档副本,并在其上应用给定的更改列表。但是由于 TextChange 的实例只给了我们插入/删除符号的数量(而不是符号),所以我们需要在转换原始副本时放一些特殊符号(例如“?”)来表示未知符号文档。
在对文档的原始副本应用所有更改后,我们可以将其与富文本框的更新文档进行比较,并找到未知符号和真实符号之间的映射。最后,得到我们想要的!!!
有人试过这个吗?我需要你对整个策略的建议,以及你对这种方法的看法。
问候
最佳答案
这主要取决于您对文本更改的使用。当序列同时包含插入和删除时,理论上不可能知道每个插入的细节,因为插入的某些符号可能随后被删除。因此,您必须选择您真正想要的结果:
我将技术实现这些结果中的每一个。我过去使用过这两种技术,所以我知道它们是有效的。
获取精确序列
如果您正在实现历史记录或撤消日志或搜索特定操作,则这更合适。
对于这些用途,您描述的过程可能是最好的,但有一个可能的更改:与其“查找未知符号和真实符号之间的映射”,只需向前运行扫描以查找每个“删除”的文本,然后运行它向后查找每个“插入”的文本。
换句话说:
完成后,据我们所知,您所有的“插入”和“删除”更改条目都将具有相关联的文本,并且任何插入并立即删除的文本都将是“?”符号。
求差价
这更适合于修订标记或版本比较。
对于这些用途,只需使用文本更改信息来计算可能发现更改的一组整数范围,然后使用标准差异算法来查找实际更改。这在处理增量更改时往往非常有效,但仍可为您提供最佳更新。
当您粘贴与原始段落几乎相同的替换段落时,这特别好:使用文本更改信息将指示整个段落是新的,但使用差异(即这种技术)将仅标记那些实际运行的符号不同的。
计算变化范围的代码很简单:将变化表示为四个整数(oldstart、oldend、newstart、newend)。运行每个更改:
完成后,从旧文档中提取范围 [oldstart, oldend] 和从新文档中提取范围 [newstart, newend],然后使用标准 diff 算法进行比较。
关于WPF RichTextBox TextChanged 事件 - 如何查找已删除或插入的文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2186856/