0

我正在使用代码编辑器,我想出了这组代码:

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,例如扫描接下来要突出显示的内容。

非常感谢您的帮助!更多的力量!

4

1 回答 1

0

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

您可以使用一些方法来提高性能:

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)如果您不希望它如此频繁地更新,您可以创建一个计时器来测量自上次编辑以来的延迟,如果在计时器过去之前进行了另一次编辑,则重置计时器。

于 2013-09-04T11:09:26.120 回答