2014-11-06 53 views
1

我正在使用正則表達式格式化幾個特定的​​單詞的Richtextbox編輯器。 我使用下面的代碼:使用正則表達式與richtextbox在C#

private void myrichTextBox1_TextChanged(object sender, EventArgs e) 
    { 
     // getting keywords/functions 
     string keywords = @"\b(public|private|sendln|static|namespace|Wait|using|void|foreach|in|OK|ERROR)\b"; 
     MatchCollection keywordMatches = Regex.Matches(richTextBox1.Text, keywords); 

     // getting types/classes from the text 
     string types = @"\b(Console)\b"; 
     MatchCollection typeMatches = Regex.Matches(richTextBox1.Text, types); 

     // getting comments (inline or multiline) 
     string comments = @"(\/\/.+?$|\/\*.+?\*\/)"; 
     MatchCollection commentMatches = Regex.Matches(richTextBox1.Text, comments, RegexOptions.Multiline); 

     // getting strings 
     string strings = "\".+?\""; 
     MatchCollection stringMatches = Regex.Matches(richTextBox1.Text, strings); 


     // saving the original caret position + forecolor 
     int originalIndex = richTextBox1.SelectionStart; 
     int originalLength = richTextBox1.SelectionLength; 
     Color originalColor = Color.Black; 

     // MANDATORY - focuses a label before highlighting (avoids blinking) 

      titleLabel.Focus(); 

     // removes any previous highlighting (so modified words won't remain highlighted) 
     richTextBox1.SelectionStart = 0; 
     richTextBox1.SelectionLength = richTextBox1.Text.Length; 
     richTextBox1.SelectionColor = originalColor; 


     // scanning... 
     foreach (Match m in keywordMatches) 
     { 
      richTextBox1.SelectionStart = m.Index; 
      richTextBox1.SelectionLength = m.Length; 
      richTextBox1.SelectionColor = Color.Blue; 
     } 


     foreach (Match m in typeMatches) 
     { 
      richTextBox1.SelectionStart = m.Index; 
      richTextBox1.SelectionLength = m.Length; 
      richTextBox1.SelectionColor = Color.DarkCyan; 
     } 

     foreach (Match m in commentMatches) 
     { 
      richTextBox1.SelectionStart = m.Index; 
      richTextBox1.SelectionLength = m.Length; 
      richTextBox1.SelectionColor = Color.Green; 
     } 

     foreach (Match m in stringMatches) 
     { 
      richTextBox1.SelectionStart = m.Index; 
      richTextBox1.SelectionLength = m.Length; 
      richTextBox1.SelectionColor = Color.Brown; 
     } 

     // restoring the original colors, for further writing 
     richTextBox1.SelectionStart = originalIndex; 
     richTextBox1.SelectionLength = originalLength; 
     richTextBox1.SelectionColor = originalColor; 

     // giving back the focus 
     richTextBox1.Focus(); 
    } 

由於是在文本編輯連續閃爍,因此移動了的關注標記titleLabel.Focus();。 但在推出後,其捐贈的異常以下:

類型「System.StackOverflowException」未處理的異常發生在System.Windows.Forms.dll中。

沒有titleLabel.Focus();沒有例外,但連續閃爍。

+4

更改TextChanged事件中的選擇屬性會導致TextChanged事件,該事件會更改導致TextChanged事件...無限的選擇屬性。請參閱[WinForms RichTextBox:如何異步重新格式化,而不觸發TextChanged事件](http://stackoverflow.com/questions/1457411/winforms-richtextbox-how-to-reformat-asynchronously-without-firing-) – 2014-11-06 13:24:23

+0

感謝Yuriy正確格式化。 @亞歷克斯,仍然我很困惑的解決方案。 – 2014-11-06 13:28:45

回答

1

最好的辦法可能是更改格式代碼,以便它首先計算出是否需要對文本進行任何更改,並且僅在文本框的內容應用更改時才應用更改。這種方法通過避免不必要的更新也提高了控制的效率。

另一種方法有點不好但很容易實現,那就是在處理事件的時候設置一個標誌,這樣如果事件再次發生,你就會忽略事件。例如:

private bool _updatingTextBox; 

private void myrichTextBox1_TextChanged(object sender, EventArgs e) 
{ 
    if (_updatingTextBox) 
    { 
     return; 
    } 

    _updatingTextBox = true; 

    try 
    { 
     // all your updating code goes here 
    } 
    finally 
    { 
     _updatingTextBox = false; 
    } 
}