Salve a tutti quelli che ho lavorato su un'applicazione WPF con un editor di testo questo editor di testo dovrebbe applicare alcuni stili o colorazione su alcuni token (parole chiave) per evidenziarlo e renderlo evidente ,,, il il problema è che ho provato molto duramente, ma ottengo lo stesso risultato che è quando l'utente inserisce una delle parole chiave nell'intero testo dopo che quella parola chiave è stata disegnata! immagina solo se digiti la parola chiave "string" in "C#" l'intero testo dopo che sarà colorato di blu.WPF RichTextBox Sintassi Evento di evidenziazione
Questo è stato il codice che ho usato:
static List<string> tags = new List<string>(); static List<char> specials = new List<char>(); static string text; #region ctor static MainWindow() { string[] specialWords = { "string", "char", "null" }; tags = new List<string>(specialWords); // We also want to know all possible delimiters so adding this stuff. char[] chrs = { '.', ')', '(', '[', ']', '>', '<', ':', ';', '\n', '\t', '\r' }; specials = new List<char>(chrs); } public MainWindow() { InitializeComponent(); } #endregion //Now I should check statically if the string I passed is legal and constants in my dictionary public static bool IsKnownTag(string tag) { return tags.Exists(delegate(string s) { return s.ToLower().Equals(tag.ToLower()); }); } private static bool GetSpecials(char i) { foreach (var item in specials) { if (item.Equals(i)) { return true; } } return false; } // Wow. Great. Now I should separate words, that equals to my tags. For this propose we'll create new internal structure named Tag. This will help us to save words and its' positions. new struct Tag { public TextPointer StartPosition; public TextPointer EndPosition; public string Word; } internal void CheckWordsInRun(Run theRun){ //How, let's go through our text and save all tags we have to save. int sIndex = 0; int eIndex = 0; List<Tag> m_tags = new List<Tag>(); for (int i = 0; i < text.Length; i++) { if (Char.IsWhiteSpace(text[i]) | GetSpecials(text[i])) { if (i > 0 && !(Char.IsWhiteSpace(text[i - 1]) | GetSpecials(text[i - 1]))) { eIndex = i - 1; string word = text.Substring(sIndex, eIndex - sIndex + 1); if (IsKnownTag(word)) { Tag t = new Tag(); t.StartPosition = theRun.ContentStart.GetPositionAtOffset(sIndex, LogicalDirection.Forward); t.EndPosition = theRun.ContentStart.GetPositionAtOffset(eIndex + 1, LogicalDirection.Backward); t.Word = word; m_tags.Add(t); } } sIndex = i + 1; } } //How this works. But wait. If the word is last word in my text I'll never hightlight it, due I'm looking for separators. Let's add some fix for this case string lastWord = text.Substring(sIndex, text.Length - sIndex); if (IsKnownTag(lastWord)) { Tag t = new Tag(); t.StartPosition = theRun.ContentStart.GetPositionAtOffset(sIndex, LogicalDirection.Forward); t.EndPosition = theRun.ContentStart.GetPositionAtOffset(eIndex + 1, LogicalDirection.Backward); t.Word = lastWord; m_tags.Add(t); } //How I have all my words and its' positions in list. Let's color it! Dont forget to unsubscribe! text styling fires TextChanged event. txtStatus.TextChanged -= txtStatus_TextChanged; for (int i = 0; i < m_tags.Count; i++) { try { TextRange range = new TextRange(m_tags[i].StartPosition, m_tags[i].EndPosition); range.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Blue)); range.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold); } catch { } } m_tags.Clear(); txtStatus.TextChanged += txtStatus_TextChanged; }
e qui è il testo cambiato gestore di eventi
private void txtStatus_TextChanged(object sender, TextChangedEventArgs e) { if (txtStatus.Document == null) return; TextRange documentRange = new TextRange(txtStatus.Document.ContentStart, txtStatus.Document.ContentEnd); //documentRange.ClearAllProperties(); text = documentRange.Text; //Now let's create navigator to go though the text and hightlight it TextPointer navigator = txtStatus.Document.ContentStart; while (navigator.CompareTo(txtStatus.Document.ContentEnd) < 0) { TextPointerContext context = navigator.GetPointerContext(LogicalDirection.Backward); if (context == TextPointerContext.ElementStart && navigator.Parent is Run) { CheckWordsInRun((Run)navigator.Parent); } navigator = navigator.GetNextContextPosition(LogicalDirection.Forward); } }
Tutto il consiglio o la mano sarà molto apprezzato, , Grazie in anticipo.
yessssssssssssssssssss, vi ringrazio molto signore, dal mio cuore. apprezzo davvero la tua mano – a7madx7
ho ancora un po 'di problema qui però, ogni volta che premo return (invio) e scrivo in una nuova riga il codice inizia a parole sbagliate hilight in posizioni sbagliate! – a7madx7
@ Dr.Ahmed Oh, non ho provato con le nuove linee ... Bene, guarda la mia risposta aggiornata (etichettata come correzione 1 e correzione 2). – kennyzx