Hi guys,
I have two richtextboxes that contain text. I want to go through each line and if a difference is found, it highlights that line on both textboxes and it would be good to highlight the difference itself too.
I have attached some code I have written.
Note some of the code is just an outline of the expected behavior.
Also, how would I ignore whitespace for each line?
Help is greatly appreciated.

void ToolLeftRefreshClick(object sender, EventArgs e)
		{
			String check1 = "";
                        String check2 = "";
			foreach(String rtb1line in richTextBox1.Lines)
			{
				check1 = (Text on current line : richtextbox1)
                                check2 = (Text on current line : richtextbox2)
				
				
				
				if(check1.equals(check2))
				{
					
				}
                               else
                               {
                                  Highlights the line
                                  Highlights difference

                               }
				
			}
			
			
		}

Recommended Answers

All 13 Replies

I've got no time to give you more elaborate example but the following code should give you the idea what to do:

private void button1_Click(object sender, EventArgs e)
        {
            string[] textFromRTB1 = richTextBox1.Lines;
            string[] textFromRTB2 = richTextBox2.Lines;
            richTextBox1.Clear();
            richTextBox2.Clear();
            int linesCount = 0;

            if (textFromRTB1.Length != textFromRTB2.Length)
            {
                linesCount = Math.Min(textFromRTB1.Length, textFromRTB2.Length);
                MessageBox.Show("Boxes have different number of lines.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
                linesCount = textFromRTB1.Length;

            bool checker = true;
            for (int i = 0; i < linesCount; i++)
            {
                checker = String.Equals(textFromRTB1[i], textFromRTB2[i]);

                if (!checker)
                {
                    richTextBox1.SelectionBackColor = Color.Red;
                    richTextBox2.SelectionBackColor = Color.Red;
                    richTextBox1.SelectedText = textFromRTB1[i] + "\n";
                    richTextBox2.SelectedText = textFromRTB2[i] + "\n";
                }
                else
                {
                    richTextBox1.SelectionBackColor = Color.Green;
                    richTextBox2.SelectionBackColor = Color.Green;
                    richTextBox1.SelectedText = textFromRTB1[i] + "\n";
                    richTextBox2.SelectedText = textFromRTB2[i] + "\n";
                }
            }
        }

To do more sophisticated comparisons use regular expressions (class Regex and e.x. Match).
If you want to parse the text when it is written you can use TextChanged Event...

That was perfect. Thank you so much.
One more question...
How would I get line numbers to appear to the left of the text areas?
Preferably I would like a control to be used that can be hidden, should the user decide they don't want to see the line numbers.

Help is greatly appreciated.

That's very easy... All you have to do is to add a boolean variable which will remember the user's choice (you can use for example a combobox to give a user the chance to choice). Then according to that variable you add the line number or not.
Sample code:

private void button1_Click(object sender, EventArgs e)
        {
            string[] textFromRTB1 = richTextBox1.Lines;
            string[] textFromRTB2 = richTextBox2.Lines;
            richTextBox1.Clear();
            richTextBox2.Clear();
            int linesCount = 0;
            bool lineNumVisible;
            if (comboBox1.SelectedIndex == 0)
                lineNumVisible = true;
            else
                lineNumVisible = false;

            if (textFromRTB1.Length != textFromRTB2.Length)
            {
                linesCount = Math.Min(textFromRTB1.Length, textFromRTB2.Length);
                MessageBox.Show("Boxes have different number of lines.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
                linesCount = textFromRTB1.Length;

            bool checker = true;
            for (int i = 0; i < linesCount; i++)
            {
                checker = String.Equals(textFromRTB1[i], textFromRTB2[i]);

                if (!checker)
                {
                    richTextBox1.SelectionBackColor = Color.Red;
                    richTextBox2.SelectionBackColor = Color.Red;
                    if (lineNumVisible)
                    {
                        richTextBox1.SelectedText = (i + 1).ToString() + ".  " + textFromRTB1[i] + "\n";
                        richTextBox2.SelectedText = (i + 1).ToString() + ".  " + textFromRTB2[i] + "\n";
                    }
                    else
                    {
                        richTextBox1.SelectedText = textFromRTB1[i] + "\n";
                        richTextBox2.SelectedText = textFromRTB2[i] + "\n";
                    }
                }
                else
                {
                    richTextBox1.SelectionBackColor = Color.Green;
                    richTextBox2.SelectionBackColor = Color.Green;
                    if (lineNumVisible)
                    {
                        richTextBox1.SelectedText = (i + 1).ToString() + ".  " + textFromRTB1[i] + "\n";
                        richTextBox2.SelectedText = (i + 1).ToString() + ".  " + textFromRTB2[i] + "\n";
                    }
                    else
                    {
                        richTextBox1.SelectedText = textFromRTB1[i] + "\n";
                        richTextBox2.SelectedText = textFromRTB2[i] + "\n";
                    }
                }
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // set the default value of the combobox
            comboBox1.SelectedIndex = 0;
        }

        private void btClear_Click(object sender, EventArgs e)
        {
            richTextBox1.Clear();
            richTextBox2.Clear();
            richTextBox1.SelectionBackColor = Color.White;
            richTextBox2.SelectionBackColor = Color.White;
        }

Thanks once again.
How would I get the diff code working for richtextboxes that have a different number of lines?
For example:

Rtb1 Rtb2

aaa aaa
bbb ccc
ccc ccc
aaa
bcd bcd

fff

fff

The blanks are empty lines. so, where there is the "aaa", it would highlight it and the empty line in the other richtextbox. Then, where both richtextboxes have empty lines, it would highlight both lines.

Help is greatly appreciated.

This is a sample screenshot of what the user should when the text is compared:

http://picsorlinks.com/pics/view/id/15398


The lines which are the same are highlighted in yellow, red is where lines are different, and green is where there are blank lines.

Help is appreciated.

I feel a little bit like doing your homework but OK...
Some questions:
1. what exactly do you want to do? you just want to compare 2 files and show the differences? or you give users the possibility to change the text in the boxes and compare the text?
2. do you need some fancy text formating like changing the font color, shape or size?
3. if it comes to empty line highlighting - you have to highlight the whole line or it not really important - you can highlight half of the line as well?
I need more details... but if you really need all of sophisticated features of richtextbox it can be difficult to achieve...

I feel a little bit like doing your homework but OK...
Some questions:
1. what exactly do you want to do? you just want to compare 2 files and show the differences? or you give users the possibility to change the text in the boxes and compare the text?
2. do you need some fancy text formating like changing the font color, shape or size?
3. if it comes to empty line highlighting - you have to highlight the whole line or it not really important - you can highlight half of the line as well?
I need more details... but if you really need all of sophisticated features of richtextbox it can be difficult to achieve...

Hi, Szpilona

Answers:

1. Yes, compare 2 files and show the differences . Then, every time the user changes text in either richtextbox, the files are compared and differences are shown.
2. No need for any fancy text formatting.
3. Not really important, as long as it's easy to tell which are blanks.

So there will be a problem... as far as I know richtextbox does not support selecting and coloring a line - I mean you cannot select a blank line... so any line consisting of "\r", "\n" or "\r\n" is a problem... the easiest workaround for that problem is filling empty line from left to right margin with spaces... but as in your app a user can edit the files using the same richtextboxes it would be very difficult to differentiate between empty lines and actual spaces... so basically in that case you can create your own control which inherit from richtextbox or find good workaround for your app... you can for example provide user with checkbox and one more richtextbox for editing selected file...
btw if you will always leave the lines' numbers visible the problem will be very easily solved - for empty lines only the line numbers will be highlighted...

If you are using an rich text edit just use the line breaks, most apps that compare and highlight changes in lines will highlight the actual change and the line number part of the display. In short I would just use the default action.

Thank you Szpilona and privatevoid for your replies.

Szpilona, the highlighting of just the line numbers is fine. Could you provide a simple code example? Also, how would I get the code you provided earlier to work on files that have a different number of lines?

privatevoid, could you explain your method using line breaks more?

Help is appreciated.

I did not have any time to take a closer look to that problem (a lot of work... ;()... so that's probably not the best way to accomplish that, but it works...
enjoy the code:

private void compareLines(int linesCount, string[] textFromRTB1, string[] textFromRTB2)
        {
            bool checker = true;
            for (int i = 0; i < linesCount; i++)
            {
                checker = String.Equals(textFromRTB1[i], textFromRTB2[i]);

                if (!checker)
                {
                    if (textFromRTB1[i] == String.Empty)
                        richTextBox1.SelectionBackColor = Color.Green;
                    else
                        richTextBox1.SelectionBackColor = Color.Red;
                    if (textFromRTB2[i] == String.Empty)
                        richTextBox2.SelectionBackColor = Color.Green;
                    else
                        richTextBox2.SelectionBackColor = Color.Red;
                    richTextBox1.SelectedText = (i + 1).ToString() + ". " + textFromRTB1[i] + "\n";
                    richTextBox2.SelectedText = (i + 1).ToString() + ". " + textFromRTB2[i] + "\n";
                }
                else
                {
                    if (textFromRTB1[i] == String.Empty)
                    {
                        richTextBox1.SelectionBackColor = Color.Green;
                        richTextBox2.SelectionBackColor = Color.Green;
                    }
                    else
                    {
                        richTextBox1.SelectionBackColor = Color.Yellow;
                        richTextBox2.SelectionBackColor = Color.Yellow;
                    }
                    richTextBox1.SelectedText = (i + 1).ToString() + ". " + textFromRTB1[i] + "\n";
                    richTextBox2.SelectedText = (i + 1).ToString() + ". " + textFromRTB2[i] + "\n";
                }
            }
        }

and then:

private void button1_Click(object sender, EventArgs e)
      {
          string[] textFromRTB1 = richTextBox1.Lines;
          string[] textFromRTB2 = richTextBox2.Lines;
          richTextBox1.Clear();
          richTextBox2.Clear();
          int linesCount = 0;

          if (textFromRTB1.Length == textFromRTB2.Length)
              compareLines(textFromRTB1.Length, textFromRTB1, textFromRTB2);
          else
          {
              linesCount = Math.Min(textFromRTB1.Length, textFromRTB2.Length);
              compareLines(linesCount, textFromRTB1, textFromRTB2);

              if (textFromRTB1.Length > textFromRTB2.Length)
              {
                  for (int i = textFromRTB2.Length + 1; i < textFromRTB1.Length; i++)
                  {
                      if (textFromRTB1[i] == String.Empty)
                          richTextBox1.SelectionBackColor = Color.Green;
                      else
                          richTextBox1.SelectionBackColor = Color.Red;
                      richTextBox1.SelectedText = (i + 1).ToString() + ". " + textFromRTB1[i] + "\n";
                  }
              }
              else
              {
                  for (int i = textFromRTB1.Length + 1; i < textFromRTB2.Length; i++)
                  {
                      if (textFromRTB2[i] == String.Empty)
                          richTextBox2.SelectionBackColor = Color.Green;
                      else
                          richTextBox2.SelectionBackColor = Color.Red;
                      richTextBox2.SelectedText = (i + 1).ToString() + ". " + textFromRTB2[i] + "\n";
                  }
              }
          }
      }

answers to questions from private message:
yeap... there's a little error in the code... in the:

private void button1_Click(object sender, EventArgs e)

line 18 - it was:

for (int i = textFromRTB2.Length + 1; i < textFromRTB1.Length; i++)

it should be:

for (int i = textFromRTB2.Length; i < textFromRTB1.Length; i++)

and similarly, line 29... it was:

for (int i = textFromRTB1.Length + 1; i < textFromRTB2.Length; i++)

it should be:

for (int i = textFromRTB1.Length; i < textFromRTB2.Length; i++)

if it comes to other questions there will be NO answer... from my point of view you show no effort - you only try to find somebody to do your job for you... finding that little mistake was very, very easy even for somebody completely new to C#...

I only asked if an array was the best method to use in this situation...
Anyway, thanks for all your help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.