Comment comparer le contenu de deux zones de texte enrichi et mettre en surbrillance les caractères modifiés?

Les codes que j’ai utilisés pour lire le contenu de 2 richtextbox sont les suivants:

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

Maintenant, je dois comparer le contenu des deux zones de texte enrichi et mettre en surbrillance les caractères modifiés dans les deux zones richtext. Le but est d’obtenir la différence et de mettre en évidence les caractères as in TFS (comparaison de fichiers) via l’application c #. Merci.

Modifier:

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

Ce que j’ai compris du débogage, c’est que la méthode Select ou SelectionColor ou SelectionBackColor de richTextBox1 pointant le curseur de texte a été augmentée à 7 positions après les lignes particulières exécutées. Comment maintenir la position du curseur de richTextBox1?

Un grand bravo à ArtyomZzz pour avoir indiqué la grande source de DiffMatchPatch!

Voici un morceau de code qui peindra les caractères modifiés dans deux RichTextbox lors d’un clic sur un bouton.

Commencez par télécharger le diff-match-patchsource . (! Voir la mise à jour ci-dessous!) À partir du fichier zip, copiez ‘DiffMatchPatch.cs’ et également ‘COPY’ dans votre projet, puis insérez le fichier cs dans votre projet. Ajoutez également l’espace de nom à vos clauses 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 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; } } } } 

Au début, j’essayais également de colorer les lignes modifiées dans une couleur plus claire; Cependant, cela prend beaucoup plus de travail, ne peut pas être fait (colorer toute la ligne plutôt que juste la partie avec le contenu), et ne faisait pas partie de votre question au départ.

Remarque: Il existe quatre méthodes de nettoyage post-diff différentes. Ce qui convient le mieux dépend de l’entrée et du but. Je suggère d’essayer le cleanupSemanticLossless . J’ai ajouté une troisième capture d’écran montrant le fonctionnement de ce nettoyage.

Voici une capture d’écran de la sortie: sortie originale

Et une de la nouvelle version: nouvelle capture d'écran

Capture d’écran après nettoyageSemanticLossless: 3ème capture d'écran

Mise à jour: Les sources semblent avoir bougé. Cela devrait aider ..

Comme je comprends le problème est:

  • comparer 2 fichiers
  • montrer les différences dans les fichiers dans l’application .net.

Le moyen le plus simple consiste à utiliser https://github.com/curran/google-diff-match-patch (le lien précédent était https://code.google.com/p/google-diff-match-patch/ , grâce à Paolo Costa pour commentaire)

Il peut comparer des fichiers (avec plusieurs options que vous pouvez définir) et former du HTML pour vous (avec diffs). Vous pouvez aussi écrire votre propre logique de sortie (si le HTML ne vous convient pas) – voir la méthode DiffMatchPatch.diff_prettyHtml (…) (c’est très simple).

ps

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

n’est pas la “meilleure” approche pour la comparaison de fichiers. C’est plus complexe.

Penser à voix haute ici, mais une autre façon de le faire serait:

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

Cela permettrait de parcourir les deux zones de texte enrichi en même temps et de mettre en évidence les différences. On dirait que c'est peut-être plus ce que vous cherchez.

Utilisez le lien que j'ai posté de mon autre réponse pour vous aider avec le bit de surbrillance. Ce petit morceau de code devrait aider à la comparaison de texte.