在使用 RichTextBox 创建自定义编辑器时,我遇到了使用 TextChanged 事件提供的信息查找已删除/插入文本的问题。
的实例文本更改事件参数 http://msdn.microsoft.com/en-us/library/system.windows.controls.textchangedeventargs_members.aspx有一些有用的数据,但我想它并不能满足所有需求。假设插入多个段落的场景,同时选定的文本(本身跨越多个段落)已被删除。
通过 TextChangedEventArgs 实例,您拥有文本更改的集合,每个更改仅向您提供删除或添加的符号的数量及其位置。
我想到的唯一解决方案是保留文档的副本,并对其应用给定的更改列表。但是由于 TextChange 的实例只提供了插入/删除符号的数量(而不是符号),因此我们在转换原始副本时需要放置一些特殊符号(例如“?”)来表示未知符号文档。
将所有更改应用到文档的原始副本后,我们可以将其与 RichTextBox 的更新文档进行比较,并找到未知符号与真实符号之间的映射。最后,得到我们想要的!
以前有人尝试过这个吗?我需要您对整个策略的建议,以及您对这种方法的看法。
Regards
这主要取决于您对文本更改的使用。当序列包含插入和删除时,理论上不可能知道每个插入的细节,因为插入的一些符号可能随后被删除。因此,您必须选择您真正想要的结果:
- 出于某些目的,您必须知道确切的sequence即使某些插入的符号必须保留为“?”,也会发生变化。
- 出于其他目的,您必须确切地知道新文本与旧文本有何不同,但不知道更改的确切顺序。
我将采用技巧来实现这些结果。我过去曾使用过这两种技术,所以我知道它们是有效的。
为了得到准确的序列
如果您要实现历史记录或撤消日志或搜索特定操作,则这更合适。
对于这些用途,您描述的过程可能是最好的,有一个可能的更改:而不是“查找未知符号和真实符号之间的映射”,只需向前运行扫描以查找每个“删除”的文本,然后运行它向后查找每个“插入”的文本。
换句话说:
从初始文本开始并按顺序处理更改。对于每个插入,插入“?”符号。对于每次删除,删除指定数量的符号并将其记录为删除的文本。
从最终文本开始,并以相反的顺序处理更改。对于每个delete, 插入 '?'符号。对于每个insert,删除指定数量的符号并将其记录为插入的文本。
完成此操作后,据我们所知,所有“插入”和“删除”更改条目都将具有关联文本,并且插入并立即删除的任何文本都将是“?”符号。
为了得到差异
这更适合修订标记或版本比较。
对于这些用途,只需使用文本更改信息来计算可能在其中找到更改的一组整数范围,然后使用标准 diff 算法来查找实际更改。这在处理增量更改方面往往非常有效,但仍然为您提供最佳更新。
当您粘贴与原始段落几乎相同的替换段落时,这特别好:使用文本更改信息将指示整个段落是新的,但使用 diff(即此技术)将仅标记那些实际上是的符号运行不同的。
计算变化范围的代码很简单:将变化表示为四个整数(oldstart、oldend、newstart、newend)。运行每个更改:
- 如果changestart在newstart之前,则将newstart减少到changestart,并减少oldstart等量
- 如果changeend在newend之后,则将newend增加到changeend,并增加oldend等量
完成此操作后,从旧文档中提取范围 [oldstart, oldend] 并从新文档中提取范围 [newstart, newend],然后使用标准 diff 算法对它们进行比较。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)