2014-11-06 1 views
1

Я делаю Richtextbox Editor с регулярным выражением для форматирования нескольких конкретных слов. Я использую ниже код:Исключение при использовании Regex с 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 ... ad infinitum. См. [WinForms RichTextBox: как переформатировать асинхронно, не запуская событие TextChanged] (http://stackoverflow.com/questions/1457411/winforms-richtextbox-how-to-reformat-asynchronously-without-firing-) –

+0

Спасибо Юрию за правильное верстка. @ Алекс, Тем не менее я запутался в решении. –

ответ

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

 Смежные вопросы

  • Нет связанных вопросов^_^