¿Cómo comparar dos contenidos de cuadro de texto enriquecido y resaltar los caracteres que se cambian?

El código que utilicé para leer los 2 contenidos del richtextbox es el siguiente:

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

Ahora, necesito comparar los dos contenidos del cuadro de texto enriquecido y resaltar los caracteres que se cambian en ambos richtextboxes. El propósito es obtener la diferencia y resaltar los caracteres as in TFS (comparando archivos) a través de la aplicación c #. Gracias.

Editar:

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

Lo que entendí de la depuración es que el método Select o SelectionColor o SelectionBackColor de richTextBox1 que señala el cursor de texto aumentó a 7 posiciones después de las líneas particulares ejecutadas. Cómo mantener la posición del cursor de richTextBox1?

¡Enhorabuena a ArtyomZzz por señalar a la gran fuente de DiffMatchPatch!

Aquí hay una pieza de código que pintará los caracteres modificados en dos cuadros de texto enriquecidos al hacer clic en un botón.

Primero descarga el diff-match-patchsource . (! Consulte la actualización a continuación!) Desde el archivo zip copie ‘DiffMatchPatch.cs’ y también ‘COPY’ en su proyecto y incluya el archivo cs en su proyecto. También agregue el espacio de nombres a sus cláusulas de uso.

 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 diffs; // chunks for formatting the two RTBs: List chunklist1; List 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 collectChunks(RichTextBox RTB) { RTB.Text = ""; List chunkList = new List(); 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 theChunks) { foreach (Chunk ch in theChunks) { RTB.Select(ch.startpos, ch.length); RTB.SelectionBackColor = ch.BackColor; } } } } 

Al principio, también intenté colorear las líneas modificadas como un todo en un color más claro; sin embargo, eso requiere mucho más trabajo, no se puede hacer (colorear toda la línea en lugar de simplemente la parte con contenido), y no fue parte de su pregunta, en primer lugar …

Nota: hay cuatro métodos de limpieza post-diff diferentes. Cuál es el más adecuado dependerá de la entrada y el propósito. Sugiero probar la cleanupSemanticLossless . He agregado una tercera captura de pantalla que muestra cómo funciona esta limpieza

Aquí hay una captura de pantalla de la salida: salida original

Y una de la nueva versión: nueva captura de pantalla

Captura de pantalla después de cleanupSemanticLossless: Tercera captura de pantalla

Actualización: las fonts parecen haberse movido. Esto debería ayudar …

Como yo entiendo el problema es:

  • comparar 2 archivos
  • mostrar diferencias en los archivos en la aplicación .net

La forma más sencilla es usar https://github.com/curran/google-diff-match-patch (el enlace anterior era https://code.google.com/p/google-diff-match-patch/ , gracias a Paolo Costa para comentario)

Puede comparar archivos (con varias opciones que puede configurar) y formar Html para usted (con diffs). También puede escribir su propia lógica para la salida (si html no es adecuado para usted) – vea el método DiffMatchPatch.diff_prettyHtml (…) (es muy simple).

PD

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

no es el “mejor” enfoque para la comparación de archivos. Es más complejo.

Solo pensar en voz alta aquí, pero otra forma de hacerlo sería:

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

Esto atravesaría ambos cuadros de texto enriquecidos al mismo tiempo y resaltaría las diferencias. Parece que puede ser más de lo que estás buscando.

Use el enlace que publiqué de mi otra respuesta para ayudarlo junto con el aspecto destacado. Este pequeño fragmento de código debería ayudar con la comparación de texto.