【问题标题】:WPF RichTextBox TextChanged event - how to find deleted or inserted text?WPF RichTextBox TextChanged 事件 - 如何查找已删除或插入的文本?
【发布时间】:2023-03-30 10:10:01
【问题描述】:

在使用 RichTextBox 创建自定义编辑器时,我遇到了使用 TextChanged 事件提供的信息查找已删除/插入的文本的问题。

TextChangedEventArgs 的实例有一些有用的数据,但我想它并不能满足所有需求。假设在插入多个段落的情况下,同时删除了选定的文本(它本身跨越了多个段落)。

使用 TextChangedEventArgs 的实例,您有一个文本更改的集合,每个更改只为您提供删除或添加符号的数量及其位置。

我想到的唯一解决方案是保留一份文档副本,并在其上应用给定的更改列表。但是由于 TextChange 的实例只给我们插入/删除符号的数量(而不是符号),所以我们需要在转换原始副本时放置一些特殊符号(例如,'?')来表示未知符号文件。

在对文档的原始副本应用所有更改后,我们可以将其与richtextbox 的更新文档进行比较,并找到未知符号与真实符号之间的映射。最后,得到我们想要的!!!

以前有人试过吗?我需要你对整个策略的建议,以及你对这种方法的看法。

问候

【问题讨论】:

    标签: wpf editor richtextbox undo-redo


    【解决方案1】:

    这主要取决于你使用的文字变化。当序列包括插入和删除时,理论上不可能知道每个插入的细节,因为插入的一些符号可能随后被删除。因此,您必须选择您真正想要的结果:

    • 出于某些目的,您必须知道更改的确切顺序,即使某些插入的符号必须保留为“?”。
    • 出于其他目的,您必须确切地知道新文本与旧文本有何不同,而不是确切的更改顺序。

    我将使用技术来实现这些结果中的每一个。我过去使用过这两种技术,所以我知道它们很有效。

    要得到准确的序列

    如果您正在实施历史记录或撤消日志或搜索特定操作,这更合适。

    对于这些用途,您描述的过程可能是最好的,有一个可能的变化:而不是“查找未知符号和真实符号之间的映射”,只需向前运行扫描以查找每个“删除”的文本然后向后运行以查找每个“插入”的文本。

    换句话说:

    1. 从初始文本开始,按顺序处理更改。对于每个插入,插入“?”符号。对于每次删除,删除指定数量的符号,并将它们记录为删除的文本。

    2. 从最终文本开始,以相反的顺序处理更改。对于每个删除,插入“?”符号。对于每个插入,删除指定数量的符号,并将它们记录为插入的文本。

    完成后,据我们所知,您的所有“插入”和“删除”更改条目都将具有关联的文本,任何插入并立即删除的文本都将是“?”符号。

    要与众不同

    这更适合修订标记或版本比较。

    对于这些用途,只需使用文本更改信息来计算可能会发现更改的一组整数范围,然后使用标准差异算法来查找实际更改。这在处理增量更改方面往往非常有效,但仍可为您提供最佳更新。

    当您粘贴与原始段落几乎相同的替换段落时,这特别好:使用文本更改信息将指示整个段落是新的,但使用差异(即这种技术)将仅标记那些符号运行这实际上是不同的。

    计算变化范围的代码很简单:将变化表示为四个整数(oldstart、oldend、newstart、newend)。运行每个更改:

    1. 如果 changestart 在 newstart 之前,则将 newstart 减少到 changestart 并减少 oldstart 等量
    2. 如果 changeend 在 newend 之后,则将 newend 增加到 changeend 并增加 oldend 等量

    完成后,从旧文档中提取范围 [oldstart, oldend] 和从新文档中提取范围 [newstart, newend],然后使用标准 diff 算法进行比较。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多