如何比较两个富文本框内容并突出显示已更改的字符?(How to compare two rich text box contents and highlight the characters that

编程入门 行业动态 更新时间:2024-10-23 09:23:08
如何比较两个富文本框内容并突出显示已更改的字符?(How to compare two rich text box contents and highlight the characters that are changed?)

我用于阅读2 richtextbox内容的代码如下所示:

richTextBox1.Text = File.ReadAllText(tfsVersionFilePath); richTextBox2.Text = File.ReadAllText(dbVersionFilePath);

现在,我需要比较两个富文本框的内容并突出显示在两个richtextbox中更改的字符。 目的是通过C#应用程序获得差异并突出显示as in TFS (比较文件)中的字符。 谢谢。

编辑:

int length = (richTextBox1.Text.Length > richTextBox2.Text.Length) ? richTextBox1.Text.Length : richTextBox2.Text.Length; for (int i = 0; i < length; i++) { if (richTextBox1.Text[i] != richTextBox2.Text[i]) { /* and then start your highlight selection here, this is where some difference between the two rich text boxes begins */ richTextBox1.Select(i, 1); richTextBox1.SelectionColor = System.Drawing.Color.Yellow; richTextBox1.SelectionBackColor = System.Drawing.Color.Red; } }

我从调试中了解到,richTextBox1的Select或SelectionColor或SelectionBackColor方法在执行特定行后将文本光标指向了7个位置 。 如何保持 richTextBox1 的光标位置

Code that I used for reading the 2 richtextbox contents are as follows:

richTextBox1.Text = File.ReadAllText(tfsVersionFilePath); richTextBox2.Text = File.ReadAllText(dbVersionFilePath);

Now, I need to compare the two rich text box contents and highlight the characters that are changed in both richtextboxes. Purpose is to get the difference and highlight the characters as in TFS(comparing files) through c# application. Thanks.

Edit:

int length = (richTextBox1.Text.Length > richTextBox2.Text.Length) ? richTextBox1.Text.Length : richTextBox2.Text.Length; for (int i = 0; i < length; i++) { if (richTextBox1.Text[i] != richTextBox2.Text[i]) { /* and then start your highlight selection here, this is where some difference between the two rich text boxes begins */ richTextBox1.Select(i, 1); richTextBox1.SelectionColor = System.Drawing.Color.Yellow; richTextBox1.SelectionBackColor = System.Drawing.Color.Red; } }

What I understood from debugging is that the Select or SelectionColor or SelectionBackColor method of richTextBox1 pointing the text cursor increased to 7 positions after the particular lines executed. How to maintain the cursor position of richTextBox1 ?

最满意答案

首先感谢ArtyomZzz指出DiffMatchPatch的伟大来源!

这是一段代码,它会在点击一个按钮时在两个RichTextbox中绘制已更改的字符。

首先下载diff-match-patchsource 。 (!请参阅下面的更新!)从zip文件复制'DiffMatchPatch.cs'和'COPY'到您的项目,并在您的项目中包含cs文件。 还要将命名空间添加到您的使用子句中。

using DiffMatchPatch; namespace RTF_diff { public partial class Form1 : Form { public Form1() { InitializeComponent(); } // this is the diff object; diff_match_patch DIFF = new diff_match_patch(); // these are the diffs List<Diff> diffs; // chunks for formatting the two RTBs: List<Chunk> chunklist1; List<Chunk> chunklist2; // two color lists: Color[] colors1 = new Color[3] { Color.LightGreen, Color.LightSalmon, Color.White }; Color[] colors2 = new Color[3] { Color.LightSalmon, Color.LightGreen, Color.White }; public struct Chunk { public int startpos; public int length; public Color BackColor; } private void button1_Click(object sender, EventArgs e) { diffs = DIFF.diff_main(RTB1.Text, RTB2.Text); DIFF.diff_cleanupSemanticLossless(diffs); // <--- see note ! chunklist1 = collectChunks(RTB1); chunklist2 = collectChunks(RTB2); paintChunks(RTB1, chunklist1); paintChunks(RTB2, chunklist2); RTB1.SelectionLength = 0; RTB2.SelectionLength = 0; } List<Chunk> collectChunks(RichTextBox RTB) { RTB.Text = ""; List<Chunk> chunkList = new List<Chunk>(); foreach (Diff d in diffs) { if (RTB == RTB2 && d.operation == Operation.DELETE) continue; // ** if (RTB == RTB1 && d.operation == Operation.INSERT) continue; // ** Chunk ch = new Chunk(); int length = RTB.TextLength; RTB.AppendText(d.text); ch.startpos = length; ch.length = d.text.Length; ch.BackColor = RTB == RTB1 ? colors1[(int)d.operation] : colors2[(int)d.operation]; chunkList.Add(ch); } return chunkList; } void paintChunks(RichTextBox RTB, List<Chunk> theChunks) { foreach (Chunk ch in theChunks) { RTB.Select(ch.startpos, ch.length); RTB.SelectionBackColor = ch.BackColor; } } } }

起初我试图以更浅的颜色为整体着色变化的线条; 然而,这需要更多的工作,不可能完成(着色整条线而不是仅包含内容的部分),并且首先不是你问题的一部分。

注意:有四种不同的post-diff清理方法。 哪一个最适合取决于输入和目的。 我建议尝试cleanupSemanticLossless 。 我添加了第三张屏幕截图,显示了这种清理的工作原理

以下是输出的屏幕截图: 原始输出

而其中一个新版本: 新的截图

cleanupSemanticLossless后的屏幕截图: 3rd截图

更新:消息来源似乎已经移动。 这应该有所帮助..

First kudos to ArtyomZzz for pointing to the great source of DiffMatchPatch!

Here is a piece of code the will paint the changed characters in two RichTextboxes upon a button click.

First download the diff-match-patchsource. (!See update below!) From the zip file copy 'DiffMatchPatch.cs' and also 'COPY' to your project and inlude the cs file in you project. Also add the namespace to your using clauses.

using DiffMatchPatch; namespace RTF_diff { public partial class Form1 : Form { public Form1() { InitializeComponent(); } // this is the diff object; diff_match_patch DIFF = new diff_match_patch(); // these are the diffs List<Diff> diffs; // chunks for formatting the two RTBs: List<Chunk> chunklist1; List<Chunk> chunklist2; // two color lists: Color[] colors1 = new Color[3] { Color.LightGreen, Color.LightSalmon, Color.White }; Color[] colors2 = new Color[3] { Color.LightSalmon, Color.LightGreen, Color.White }; public struct Chunk { public int startpos; public int length; public Color BackColor; } private void button1_Click(object sender, EventArgs e) { diffs = DIFF.diff_main(RTB1.Text, RTB2.Text); DIFF.diff_cleanupSemanticLossless(diffs); // <--- see note ! chunklist1 = collectChunks(RTB1); chunklist2 = collectChunks(RTB2); paintChunks(RTB1, chunklist1); paintChunks(RTB2, chunklist2); RTB1.SelectionLength = 0; RTB2.SelectionLength = 0; } List<Chunk> collectChunks(RichTextBox RTB) { RTB.Text = ""; List<Chunk> chunkList = new List<Chunk>(); foreach (Diff d in diffs) { if (RTB == RTB2 && d.operation == Operation.DELETE) continue; // ** if (RTB == RTB1 && d.operation == Operation.INSERT) continue; // ** Chunk ch = new Chunk(); int length = RTB.TextLength; RTB.AppendText(d.text); ch.startpos = length; ch.length = d.text.Length; ch.BackColor = RTB == RTB1 ? colors1[(int)d.operation] : colors2[(int)d.operation]; chunkList.Add(ch); } return chunkList; } void paintChunks(RichTextBox RTB, List<Chunk> theChunks) { foreach (Chunk ch in theChunks) { RTB.Select(ch.startpos, ch.length); RTB.SelectionBackColor = ch.BackColor; } } } }

At first I was trying to also color the changed lines as a whole in a lighter color; however that takes considerably more work, can't be done (coloring the whole line as opposed to just the part with content), and was not part of your question in the first place..

Note: There are four different post-diff cleanup methods. Which is best suited will depend on the input and purpose. I suggest trying the cleanupSemanticLossless. I have added a 3rd screenshot showing how this cleanup works

Here is a screenshot of the output: original output

And one of the new version: new screenshot

Screenshot after cleanupSemanticLossless: 3rd screenshot

Update: The sources seem to have moved. This should help..

更多推荐

本文发布于:2023-04-29 23:22:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1336383.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:文本框   字符   两个   内容   compare

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!