天天看點

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

一、RichTextBox基本設定

二、實作文法高亮

三、關鍵字提示

四、實作行号

就簡單快速得開發文本編輯器TextBox 最為簡單,大家用得也多,缺點是無法實作複雜的操作。RichTextBox雖然是則功能比它強大很多。

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

這裡要實作以下功能的編輯器:

1、實作文法高亮;

2、關鍵字提示;

3、行号。

顯然TextBox 無法完成我們的任務,雖然都派生自TextBoxBase,但就控制力而言RichTextBox比它優秀很多。這裡選用RichTextBox嘗試開發。

注:以下隻讨論簡單開發,不考慮複雜的關鍵字查找機制。

一、RichTextBox基本設定

這裡先建立一個工程,建立窗體Form1。

可以簡單添加RichTextBox控件,可以在Form1_Load中建立。代碼如下:

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

複制  

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

儲存

 this                .WindowState = System.Windows.Forms.FormWindowState.Maximized;

RichTextBox rich =          new                 RichTextBox();
rich.Multiline =          true                ;
rich.Height =          this                .Height - 100;
rich.Width =          this                .Width - 100;
rich.Left = 40;
rich.Top = 40;
rich.WordWrap =          true                ;
rich.Text =          "12345678"                ;
rich.ScrollBars = RichTextBoxScrollBars.ForcedVertical;
         this                .Controls.Add(rich);      

這樣就建立了簡單的RichTextBox,寬度和高度都設定了。沒有做Form1窗體縮放的處理。

二、實作文法高亮

在RichTextBox裡實作文法高亮還是非常簡單的。可以使用

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

複制  

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

儲存

rich.Select(0, 1);
rich.SelectionFont =          new                 Font(         "宋體"                , 12, (FontStyle.Regular));
rich.SelectionColor = Color.Blue;      

意思是,先選擇第一個字母,按上面的設定,選擇到了數字‘1’,然後設定這個字的字型大小,再設定字的顔色。

如果對關鍵字進行處理(這裡隻處理光标向後流動的情況)

首先添加輸入事件

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

複制  

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

儲存

rich.KeyDown +=          new                 KeyEventHandler(rich_KeyDown);            //這一行添加到Form1_Load中              void                 rich_KeyDown(         object                 sender, KeyEventArgs e)
{
          //throw new Exception("The method or operation is not implemented.");                }      

建立關鍵字

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

複制  

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

儲存

 public              static                 List<         string                > AllClass()
{
    List<         string                > list =          new                 List<         string                >();
    list.Add(         "function"                );
    list.Add(         "return"                );
    list.Add(         "class"                );
    list.Add(         "new"                );
    list.Add(         "extends"                );
    list.Add(         "var"                );
             return                 list;
}      

當KeyDown事件發生時,向前查找

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

複制  

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

儲存

 //傳回搜尋字元              public              static              string                 GetLastWord(         string                 str,          int                 i)
{
             string                 x = str;
    Regex reg =          new                 Regex(         @"/s+[a-z]+/s*"                , RegexOptions.RightToLeft);
    x = reg.Match(x).Value;

    Regex reg2 =          new                 Regex(         @"/s"                );
    x = reg2.Replace(x,          ""                );
             return                 s;
}      
C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

複制  

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

儲存

 void                 rich_KeyDown(         object                 sender, KeyEventArgs e)
{
    RichTextBox rich = (RichTextBox) sender;
             //throw new Exception("The method or operation is not implemented.");              string                 s = GetLastWord(rich.Text, rich.SelectionStart);

             if                 (AllClass().IndexOf(s) > -1)
    {
        MySelect(rich, rich.SelectionStart, s, Color.CadetBlue,          true                );
    }
}      
C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

複制  

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

儲存

 //設定顔色              public              static              void                 MySelect(System.Windows.Forms.RichTextBox tb,          int                 i,          string                 s, Color c,          bool                 font)
{
    tb.Select(i - s.Length, s.Length);
    tb.SelectionColor = c;
             //是否改變字型              if                 (font)
        tb.SelectionFont =          new                 Font(         "宋體"                , 12, (FontStyle.Bold));
             else                
        tb.SelectionFont =          new                 Font(         "宋體"                , 12, (FontStyle.Regular));
             //以下是把光标放到原來位置,并把光标後輸入的文字重置                    tb.Select(i, 0);
    tb.SelectionFont =          new                 Font(         "宋體"                , 12, (FontStyle.Regular));
    tb.SelectionColor = Color.Black;
}      

這樣就完成了高亮工作。

三、關鍵字提示

實作關鍵字提示也是在KeyDown中實作,在提示字種搜尋GetLastWord傳回的文字,如果前半部分比對。那麼就建立ListBox控件。

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

複制  

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

儲存

 void                 tb_KeyDown(         object                 sender, KeyEventArgs e)
{
    RichTextBox tb = (RichTextBox) sender;
             if                 (         /*條件搜尋到比對字元*/                )
    {
                 //搜尋ListBox是否已經被建立                        Control[] c = tb.         Controls.Find                (         "mylb"                ,          false                );
                 if                 (c.Length > 0)
            ((ListBox) c[0]).Dispose();           //如果被建立則釋放                
        ListBox lb =          new                 ListBox();
        lb.Name =          "mylb"                ;
        lb.Items.Add(         "asdasdasd"                );
        lb.Items.Add(         "asdasdasd"                );
        lb.Items.Add(         "asdasdasd"                );
        lb.Items.Add(         "asdasdasd"                );
        lb.Items.Add(         "asdasdasd"                );
        lb.Items.Add(         "asdasdasd"                );
        lb.Items.Add(         "asdasdasd"                );
        lb.Show();
        lb.TabIndex = 100;
        lb.Location = tb.GetPositionFromCharIndex(tb.SelectionStart);
        lb.Left += 10;
        tb.Controls.Add(lb);
    }
}      

當然,另外一面,如果建立ListBox,而又在RichTextBox 點選了滑鼠也去釋放。

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

複制  

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

儲存

 void                 rich_MouseClick(         object                 sender, MouseEventArgs e)
{
    RichTextBox tb = (RichTextBox) sender;
    Control[] c = tb.         Controls.Find                (         "mylb"                ,          false                );
             if                 (c.Length > 0)
        ((ListBox) c[0]).Dispose();
}      

當然還得在Form1_Load裡注冊事件

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

複制  

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

儲存

rich.MouseClick +=          new                 MouseEventHandler(rich_MouseClick);      

然後設定ListBox 被選擇後用被選擇的關鍵字替換前文搜尋到的字元。

下面我們來看看實作行号。

四、實作行号

這個是RichTextBox 唯一令我遺憾的地方,居然無法實作行号問題。為什麼呢?我首先想到的是自己畫。用rich.CreateGraphics()來畫。但是,由于畫的時候發生在窗體被建立時,是以畫不成功,而被RichTextBox 本身的繪制給覆寫了。

然後我選擇了在裡面添加Label控件

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

複制  

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

儲存

Label l =          new                 Label();
l.Name =          "l"                ;
l.Top = 0;
l.TextAlign = ContentAlignment.TopRight;
l.Width = 40;
l.Text =          "1"                ;
l.Font =          new                 Font(         "宋體"                , 12, (FontStyle.Regular));
l.Height =          this                .Height;
l.BackColor = Color.Gray;
l.BorderStyle = BorderStyle.None;
rich.Controls.Add(l);

rich.SelectionIndent = 40;      

rich.SelectionIndent = 40;是把光标對齊到左邊距40的位置,防止光标被Label覆寫。

實作編号還不是太難。麻煩出在如何讓Lable能跟随RichTextBox 的滾動條滾動。不說實作的 細節,我就假設,如果滾動條向上滾,那麼Lable的Top屬性增加,反之則減少。但是,RichTextBox 居然無法對ScollBar進行監測。

根本每辦法知道滾動條滾動了多少位置,甚至都沒辦法知道滾動條滾動的方向。

嘗試去除滾動條,然後之間添加新的滾動條

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

複制  

C#開發高亮文法編輯器(一)——TextBox ,RichTextBox

儲存

VScrollBar vs =          new                 VScrollBar();
         //vs.Dock = DockStyle.Right;                vs.Name =          "vs"                ;
vs.Maximum = 0;
vs.Minimum = 0;
vs.MaximumSize =          new                 Size(0, 0);
vs.Top = 0;
vs.Left = rich.Parent.Width - 100 - 22;
vs.Height = rich.Parent.Height - 100 - 1;
vs.Value = 0;
vs.Scroll +=          new                 ScrollEventHandler(vs_Scroll);

rich.Controls.Add(vs);      

但是非常難于實作同步滾動,位置很難控制。這個就是目前遇到的RichTextBox 的最大局限性了,非常遺憾,無法開發出這個功能。