如何比较两个富文本框内容并突出显示更改的字符?

时间:2014-07-22 12:18:59

标签: c# .net winforms richtextbox

我用于阅读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的SelectSelectionColorSelectionBackColor方法将增加到7个位置执行。如何保持richTextBox1的光标位置

3 个答案:

答案 0 :(得分:12)

首先赞扬ArtyomZzz指向DiffMatchPatch的伟大来源!

这是一段代码,点按一下按钮就会在两个RichTextbox中绘制更改过的字符。

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

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;
        }

    }

  }
}

起初我还尝试将变化的线条整体换成浅色;然而,这需要更多的工作,无法完成(着色整行而不仅仅是内容部分),并且首先不是你问题的一部分..

注意:有四种不同的后差异清理方法。哪种最适合取决于输入和目的。我建议你试试cleanupSemanticLossless。我添加了第3个屏幕截图,显示了此清理的工作原理

以下是输出的屏幕截图: original output

其中一个新版本: new screenshot

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

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

答案 1 :(得分:3)

据我所知,问题是:

  • 比较2个文件
  • 显示.net应用程序中文件的差异。

最简单的方法是使用https://github.com/curran/google-diff-match-patch(之前的链接为https://code.google.com/p/google-diff-match-patch/,感谢Paolo Costa发表评论)

它可以比较文件(你可以设置几个选项)并为你形成Html(带差异)。您也可以编写自己的输出逻辑(如果html不适合您) - 请参阅DiffMatchPatch.diff_prettyHtml(...)方法(非常简单)。

P.S。

  

if(richTextBox1.Text [i]!= richTextBox2.Text [i])

不是最好的&#34;文件比较的方法。它更复杂。

答案 2 :(得分:0)

在这里大声思考,但另一种方法是:

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 */
   }

这将同时遍历两个富文本框并突出显示差异。听起来它可能更像你正在寻找的东西。

使用我在其他答案中发布的链接来帮助您突出显示位。这段代码应该有助于文本比较。