避免扫描EntireRich文本框高亮显示

本文关键字:高亮 显示 文本 EntireRich 扫描 | 更新日期: 2023-09-27 18:22:06

我正在开发一个代码编辑器,我想出了这组代码:

public class Test2 : Form {
  RichTextBox m_rtb = null;
  public static void Main() {
    Application.Run(new Test2());
  }
  public Test2() {
    Text = "Test2";
    ClientSize = new Size(400, 400);
    m_rtb = new RichTextBox();
    m_rtb.Multiline = true;
    m_rtb.WordWrap = false;
    m_rtb.AcceptsTab = true;
        m_rtb.ScrollBars = RichTextBoxScrollBars.ForcedBoth;
    m_rtb.Dock = DockStyle.Fill;
    m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);
    m_rtb.SelectionColor = Color.Black;
    Controls.Add(m_rtb);
    Parse();
    m_rtb.TextChanged += new EventHandler(this.TextChangedEvent);
  }
  void Parse() {
    String inputLanguage = 
      "// Comment.'n" +
      "using System;'n" + "'n" +
      "public class Stuff : Form { 'n" +
      "  public static void Main(String args) {'n" +
      "  }'n" +   
      "}'n" ; 
    // Foreach line in input,
    // identify key words and format them when adding to the rich text box.
    Regex r = new Regex("''n");
    String [] lines = r.Split(inputLanguage);
    foreach (string l in lines) {
      ParseLine(l);
    }    
  }
  void ParseLine(string line) {
    Regex r = new Regex("([ ''t{}();])");
    String [] tokens = r.Split(line);
    foreach (string token in tokens) {
      // Set the token's default color and font.
      m_rtb.SelectionColor = Color.Black;
      m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);
      // Check for a comment.
      if (token == "//" || token.StartsWith("//")) {
        // Find the start of the comment and then extract the whole comment.
        int index = line.IndexOf("//");
        string comment = line.Substring(index, line.Length - index);
        m_rtb.SelectionColor = Color.LightGreen;
        m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);
        m_rtb.SelectedText = comment;
        break;
      }
      // Check whether the token is a keyword. 
      String [] keywords = { "public", "void", "using", "static", "class" }; 
      for (int i = 0; i < keywords.Length; i++) {
        if (keywords[i] == token) {
          // Apply alternative color and font to highlight keyword.
          m_rtb.SelectionColor = Color.Blue;
          m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Bold);
          break;
        }
      }
      m_rtb.SelectedText = token;
    }    
    m_rtb.SelectedText = "'n";
  } 
  private void TextChangedEvent(object sender, EventArgs e) {
    // Calculate the starting position of the current line.
    int start = 0, end = 0;
    for (start = m_rtb.SelectionStart - 1; start > 0; start--) {
      if (m_rtb.Text[start] == ''n')  { start++; break; }
    }
    // Calculate the end position of the current line.
    for (end = m_rtb.SelectionStart; end < m_rtb.Text.Length; end++) {
      if (m_rtb.Text[end] == ''n') break;
    }
    // Extract the current line that is being edited.
    String line = m_rtb.Text.Substring(start, end - start);
    // Backup the users current selection point.
    int selectionStart = m_rtb.SelectionStart;
    int selectionLength = m_rtb.SelectionLength;
    // Split the line into tokens.
    Regex r = new Regex("([ ''t{}();])");
    string [] tokens = r.Split(line);
    int index = start;
    foreach (string token in tokens) {
      // Set the token's default color and font.
      m_rtb.SelectionStart = index;
      m_rtb.SelectionLength = token.Length;
      m_rtb.SelectionColor = Color.Black;
      m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);
      // Check for a comment.
      if (token == "//" || token.StartsWith("//")) {
        // Find the start of the comment and then extract the whole comment.
        int length = line.Length - (index - start);
        string commentText = m_rtb.Text.Substring(index, length);
        m_rtb.SelectionStart = index;
        m_rtb.SelectionLength = length;
        m_rtb.SelectionColor = Color.LightGreen;
        m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Regular);
        break;
      }
      // Check whether the token is a keyword. 
      String [] keywords = { "public", "void", "using", "static", "class" }; 
      for (int i = 0; i < keywords.Length; i++) {
        if (keywords[i] == token) {
          // Apply alternative color and font to highlight keyword.        
          m_rtb.SelectionColor = Color.Blue;
          m_rtb.SelectionFont = new Font("Courier New", 10, FontStyle.Bold);
          break;
        }
      }
      index += token.Length;
    }
    // Restore the users current selection point.    
    m_rtb.SelectionStart = selectionStart;
    m_rtb.SelectionLength = selectionLength;  
  } 
}

问题是每次我按空格键或键入时,整个代码编辑器都会像搜索突出显示的内容一样不断扫描,我觉得这有点烦人。。。

所以我只想寻求可能的解决方案。。。以避免像扫描下一步要突出显示的内容那样突出显示整个richtextbox。

提前感谢您的帮助!更强大!

避免扫描EntireRich文本框高亮显示

我在你最近的问题中回答了这个问题,但如果其他人正在阅读但没有找到,我会把它发布在这里(因为这是专门关于性能的):

您可以使用以下几种方法来提高性能:

1) 您可以通过从当前选择中获取文本范围来获取用户正在编辑的行。我建议使用WPF的richtextbox,因为它包含了更多的功能,并且有一个有用的TextPointer类,可以用来获取当前行。然而,您似乎正在使用WinForms,因此这可以通过以下几行代码(添加一些琐碎的代码)来完成:

int start_index = RTB.GetFirstCharIndexOfCurrentLine();
int line = RTB.GetLineFromCharIndex(index);
int last_index = RTB.GetFirstCharIndexFromLine(line+1);
RTB.Select(start_index, last_index);

然后可以使用当前选择。

2) 如果您不希望它更新得如此频繁,您可以创建一个计时器来测量自上次编辑以来的延迟,如果在计时器过期之前进行了另一次编辑,则可以重置计时器。