C#开发高亮语法编辑器(一)——TextBox ,RichTextBox
生活随笔
收集整理的這篇文章主要介紹了
C#开发高亮语法编辑器(一)——TextBox ,RichTextBox
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
C#簡單實現高亮語法編輯器(一)
?????????——TextBox ,RichTextBox的局限性
一、RichTextBox基本設置
二、實現語法高亮
三、關鍵字提示
四、實現行號
就簡單快速得開發文本編輯器TextBox 最為簡單,大家用得也多,缺點是無法實現復雜的操作。RichTextBox雖然是則功能比它強大很多。
這里要實現以下功能的編輯器:
1、實現語法高亮;
2、關鍵字提示;
3、行號。
顯然TextBox 無法完成我們的任務,雖然都派生自TextBoxBase,但就控制力而言RichTextBox比它優秀很多。這里選用RichTextBox嘗試開發。
注:以下只討論簡單開發,不考慮復雜的關鍵字查找機制。
一、RichTextBox基本設置
這里先建立一個工程,建立窗體Form1。
可以簡單添加RichTextBox控件,可以在Form1_Load中建立。代碼如下:
?1?????????????this.WindowState?=?System.Windows.Forms.FormWindowState.Maximized;
?2?
?3?????????????RichTextBox?rich?=?new?RichTextBox();
?4?????????????rich.Multiline?=?true;
?5?????????????rich.Height?=?this.Height?-?100;
?6?????????????rich.Width?=?this.Width?-?100;
?7?????????????rich.Left?=?40;
?8?????????????rich.Top?=?40;
?9?????????????rich.WordWrap?=?true;
10?????????????rich.Text?=?"12345678";
11?????????????rich.ScrollBars?=?RichTextBoxScrollBars.ForcedVertical;
12?????????????this.Controls.Add(rich);
這樣就建立了簡單的RichTextBox,寬度和高度都設置了。沒有做Form1窗體縮放的處理。
二、實現語法高亮
在RichTextBox里實現語法高亮還是非常簡單的。可以使用
1?????????????rich.Select(0,1);
2?????????????rich.SelectionFont?=?new?Font("宋體",?12,?(FontStyle.Regular));
3?????????????rich.SelectionColor?=?Color.Blue;意思是,先選擇第一個字母,按上面的設置,選擇到了數字‘1’,然后設置這個字的字體大小,再設置字的顏色。
如果對關鍵字進行處理(這里只處理光標向后流動的情況)
首先添加輸入事件
1??????? rich.KeyDown?+=?new?KeyEventHandler(rich_KeyDown);?? //這一行添加到Form1_Load中
2?
3?????????void?rich_KeyDown(object?sender,?KeyEventArgs?e)
4?????????{
5?????????????//throw?new?Exception("The?method?or?operation?is?not?implemented.");
6?????????}
建立關鍵字
?1?????????public?static?List<string>?AllClass()
?2?????????{
?3?????????????List<string>?list?=?new?List<string>();
?4?????????????list.Add("function");
?5?????????????list.Add("return");
?6?????????????list.Add("class");
?7?????????????list.Add("new");
?8?????????????list.Add("extends");
?9?????????????list.Add("var");
10?????????????return?list;
11?????????}
當KeyDown事件發生時,向前查找
?1?????????//返回搜索字符
?2?????????public?static?string?GetLastWord(string?str,int?i)
?3?????????{
?4?????????????string?x?=?str;
?5?????????????Regex?reg=?new?Regex(@"\s+[a-z]+\s*",RegexOptions.RightToLeft);
?6?????????????x?=?reg.Match(x).Value;
?7?
?8?????????????Regex?reg2?=?new?Regex(@"\s");
?9?????????????x?=?reg2.Replace(x,?"");
10?????????????return?s;
11?????????}
?1?????????void?rich_KeyDown(object?sender,?KeyEventArgs?e)
?2?????????{
?3?????????????RichTextBox?rich?=?(RichTextBox)sender;
?4?????????????//throw?new?Exception("The?method?or?operation?is?not?implemented.");
?5?????????????string?s?=?GetLastWord(rich.Text,?rich.SelectionStart);
?6?
?7?????????????if?(AllClass().IndexOf(s)?>?-1)
?8?????????????{
?9?????????????????MySelect(rich,?rich.SelectionStart,?s,?Color.CadetBlue,?true);
10?????????????}
11?????????}
?1?????????//設定顏色
?2?????????public?static?void?MySelect(System.Windows.Forms.RichTextBox?tb,?int?i,?string?s,?Color?c,bool?font)
?3?????????{
?4?????????????tb.Select(i?-?s.Length,?s.Length);
?5?????????????tb.SelectionColor?=?c;
???????????????//是否改變字體
?6?????????????if(font)
?7?????????????????tb.SelectionFont?=?new?Font("宋體",?12,?(FontStyle.Bold));
?8?????????????else
?9?????????????????tb.SelectionFont?=?new?Font("宋體",?12,?(FontStyle.Regular));
?????????????????//以下是把光標放到原來位置,并把光標后輸入的文字重置
10?????????????tb.Select(i,0);
11?????????????tb.SelectionFont?=?new?Font("宋體",?12,?(FontStyle.Regular));
12?????????????tb.SelectionColor?=?Color.Black;
13?????????}
這樣就完成了高亮工作。
三、關鍵字提示
實現關鍵字提示也是在KeyDown中實現,在提示字種搜索GetLastWord返回的文字,如果前半部分匹配。那么就建立ListBox控件。
?1???????void?tb_KeyDown(object?sender,?KeyEventArgs?e)
?2?????????{
?3?????????????RichTextBox?tb?=?(RichTextBox)sender;
?4?????????????if?(//條件搜索到匹配字符)
?5?????????????{
?6?????????????????//搜索ListBox是否已經被創建
?7?????????????????Control[]?c?=?tb.Controls.Find("mylb",?false);
?8?????????????????if?(c.Length?>?0)
?9?????????????????????((ListBox)c[0]).Dispose();??//如果被創建則釋放
10?
11?????????????????ListBox?lb?=?new?ListBox();
12?????????????????lb.Name?=?"mylb";
13?????????????????lb.Items.Add("asdasdasd");
14?????????????????lb.Items.Add("asdasdasd");
15?????????????????lb.Items.Add("asdasdasd");
16?????????????????lb.Items.Add("asdasdasd");
17?????????????????lb.Items.Add("asdasdasd");
18?????????????????lb.Items.Add("asdasdasd");
19?????????????????lb.Items.Add("asdasdasd");
20?????????????????lb.Show();
21?????????????????lb.TabIndex?=?100;
22?????????????????lb.Location?=?tb.GetPositionFromCharIndex(tb.SelectionStart);
23?????????????????lb.Left?+=?10;
24?????????????????tb.Controls.Add(lb);
25?????????????}
26?????????}
當然,另外一面,如果創建ListBox,而又在RichTextBox?點擊了鼠標也去釋放。
1?????????void?rich_MouseClick(object?sender,?MouseEventArgs?e)
2?????????{
3?????????????RichTextBox?tb?=?(RichTextBox)sender;
4?????????????Control[]?c?=?tb.Controls.Find("mylb",?false);
5?????????????if?(c.Length?>?0)
6?????????????????((ListBox)c[0]).Dispose();
7?????????}
當然還得在Form1_Load里注冊事件
1?rich.MouseClick?+=?new?MouseEventHandler(rich_MouseClick);
然后設置ListBox?被選擇后用被選擇的關鍵字替換前文搜索到的字符。
下面我們來看看實現行號。
四、實現行號
這個是RichTextBox?唯一令我遺憾的地方,居然無法實現行號問題。為什么呢?我首先想到的是自己畫。用rich.CreateGraphics()來畫。但是,由于畫的時候發生在窗體被創建時,所以畫不成功,而被RichTextBox?本身的繪制給覆蓋了。
然后我選擇了在里面添加Label控件
?1????????????Label?l?=?new?Label();
?2?????????????l.Name?=?"l";
?3?????????????l.Top?=?0;
?4?????????????l.TextAlign?=?ContentAlignment.TopRight;
?5?????????????l.Width?=?40;
?6?????????????l.Text?=?"1";
?7?????????????l.Font?=?new?Font("宋體",?12,?(FontStyle.Regular));
?8?????????????l.Height?=?this.Height;
?9?????????????l.BackColor?=?Color.Gray;
10?????????????l.BorderStyle?=?BorderStyle.None;
11?????????????rich.Controls.Add(l);
12?
13?????????????rich.SelectionIndent?=?40;
?rich.SelectionIndent?=?40;是把光標對齊到左邊距40的位置,防止光標被Label覆蓋。
實現編號還不是太難。麻煩出在如何讓Lable能跟隨RichTextBox?的滾動條滾動。不說實現的 細節,我就假設,如果滾動條向上滾,那么Lable的Top屬性增加,反之則減少。但是,RichTextBox?居然無法對ScollBar進行監測。
根本每辦法知道滾動條滾動了多少位置,甚至都沒辦法知道滾動條滾動的方向。
嘗試去除滾動條,然后之間添加新的滾動條
?1?????????????VScrollBar?vs?=?new?VScrollBar();
?2?????????????//vs.Dock?=?DockStyle.Right;
?3?????????????vs.Name?=?"vs";
?4?????????????vs.Maximum?=?0;
?5?????????????vs.Minimum?=?0;
?6?????????????vs.MaximumSize?=?new?Size(0,0);
?7?????????????vs.Top?=?0;
?8?????????????vs.Left?=?rich.Parent.Width?-?100?-22;
?9?????????????vs.Height?=?rich.Parent.Height?-?100?-1;
10?????????????vs.Value?=?0;
11?????????????vs.Scroll?+=?new?ScrollEventHandler(vs_Scroll);
12?????????????
13?????????????rich.Controls.Add(vs);
但是非常難于實現同步滾動,位置很難控制。這個就是目前遇到的RichTextBox?的最大局限性了,非常遺憾,無法開發出這個功能。
birdshover
http://www.cnblogs.com/birdshover/
2007年1月30日
?????????——TextBox ,RichTextBox的局限性
一、RichTextBox基本設置
二、實現語法高亮
三、關鍵字提示
四、實現行號
就簡單快速得開發文本編輯器TextBox 最為簡單,大家用得也多,缺點是無法實現復雜的操作。RichTextBox雖然是則功能比它強大很多。
圖 1.1? 輸入框控件關系
這里要實現以下功能的編輯器:
1、實現語法高亮;
2、關鍵字提示;
3、行號。
顯然TextBox 無法完成我們的任務,雖然都派生自TextBoxBase,但就控制力而言RichTextBox比它優秀很多。這里選用RichTextBox嘗試開發。
注:以下只討論簡單開發,不考慮復雜的關鍵字查找機制。
一、RichTextBox基本設置
這里先建立一個工程,建立窗體Form1。
可以簡單添加RichTextBox控件,可以在Form1_Load中建立。代碼如下:
?1?????????????this.WindowState?=?System.Windows.Forms.FormWindowState.Maximized;
?2?
?3?????????????RichTextBox?rich?=?new?RichTextBox();
?4?????????????rich.Multiline?=?true;
?5?????????????rich.Height?=?this.Height?-?100;
?6?????????????rich.Width?=?this.Width?-?100;
?7?????????????rich.Left?=?40;
?8?????????????rich.Top?=?40;
?9?????????????rich.WordWrap?=?true;
10?????????????rich.Text?=?"12345678";
11?????????????rich.ScrollBars?=?RichTextBoxScrollBars.ForcedVertical;
12?????????????this.Controls.Add(rich);
這樣就建立了簡單的RichTextBox,寬度和高度都設置了。沒有做Form1窗體縮放的處理。
二、實現語法高亮
在RichTextBox里實現語法高亮還是非常簡單的。可以使用
1?????????????rich.Select(0,1);
2?????????????rich.SelectionFont?=?new?Font("宋體",?12,?(FontStyle.Regular));
3?????????????rich.SelectionColor?=?Color.Blue;意思是,先選擇第一個字母,按上面的設置,選擇到了數字‘1’,然后設置這個字的字體大小,再設置字的顏色。
如果對關鍵字進行處理(這里只處理光標向后流動的情況)
首先添加輸入事件
1??????? rich.KeyDown?+=?new?KeyEventHandler(rich_KeyDown);?? //這一行添加到Form1_Load中
2?
3?????????void?rich_KeyDown(object?sender,?KeyEventArgs?e)
4?????????{
5?????????????//throw?new?Exception("The?method?or?operation?is?not?implemented.");
6?????????}
建立關鍵字
?1?????????public?static?List<string>?AllClass()
?2?????????{
?3?????????????List<string>?list?=?new?List<string>();
?4?????????????list.Add("function");
?5?????????????list.Add("return");
?6?????????????list.Add("class");
?7?????????????list.Add("new");
?8?????????????list.Add("extends");
?9?????????????list.Add("var");
10?????????????return?list;
11?????????}
當KeyDown事件發生時,向前查找
?1?????????//返回搜索字符
?2?????????public?static?string?GetLastWord(string?str,int?i)
?3?????????{
?4?????????????string?x?=?str;
?5?????????????Regex?reg=?new?Regex(@"\s+[a-z]+\s*",RegexOptions.RightToLeft);
?6?????????????x?=?reg.Match(x).Value;
?7?
?8?????????????Regex?reg2?=?new?Regex(@"\s");
?9?????????????x?=?reg2.Replace(x,?"");
10?????????????return?s;
11?????????}
?1?????????void?rich_KeyDown(object?sender,?KeyEventArgs?e)
?2?????????{
?3?????????????RichTextBox?rich?=?(RichTextBox)sender;
?4?????????????//throw?new?Exception("The?method?or?operation?is?not?implemented.");
?5?????????????string?s?=?GetLastWord(rich.Text,?rich.SelectionStart);
?6?
?7?????????????if?(AllClass().IndexOf(s)?>?-1)
?8?????????????{
?9?????????????????MySelect(rich,?rich.SelectionStart,?s,?Color.CadetBlue,?true);
10?????????????}
11?????????}
?1?????????//設定顏色
?2?????????public?static?void?MySelect(System.Windows.Forms.RichTextBox?tb,?int?i,?string?s,?Color?c,bool?font)
?3?????????{
?4?????????????tb.Select(i?-?s.Length,?s.Length);
?5?????????????tb.SelectionColor?=?c;
???????????????//是否改變字體
?6?????????????if(font)
?7?????????????????tb.SelectionFont?=?new?Font("宋體",?12,?(FontStyle.Bold));
?8?????????????else
?9?????????????????tb.SelectionFont?=?new?Font("宋體",?12,?(FontStyle.Regular));
?????????????????//以下是把光標放到原來位置,并把光標后輸入的文字重置
10?????????????tb.Select(i,0);
11?????????????tb.SelectionFont?=?new?Font("宋體",?12,?(FontStyle.Regular));
12?????????????tb.SelectionColor?=?Color.Black;
13?????????}
這樣就完成了高亮工作。
三、關鍵字提示
實現關鍵字提示也是在KeyDown中實現,在提示字種搜索GetLastWord返回的文字,如果前半部分匹配。那么就建立ListBox控件。
?1???????void?tb_KeyDown(object?sender,?KeyEventArgs?e)
?2?????????{
?3?????????????RichTextBox?tb?=?(RichTextBox)sender;
?4?????????????if?(//條件搜索到匹配字符)
?5?????????????{
?6?????????????????//搜索ListBox是否已經被創建
?7?????????????????Control[]?c?=?tb.Controls.Find("mylb",?false);
?8?????????????????if?(c.Length?>?0)
?9?????????????????????((ListBox)c[0]).Dispose();??//如果被創建則釋放
10?
11?????????????????ListBox?lb?=?new?ListBox();
12?????????????????lb.Name?=?"mylb";
13?????????????????lb.Items.Add("asdasdasd");
14?????????????????lb.Items.Add("asdasdasd");
15?????????????????lb.Items.Add("asdasdasd");
16?????????????????lb.Items.Add("asdasdasd");
17?????????????????lb.Items.Add("asdasdasd");
18?????????????????lb.Items.Add("asdasdasd");
19?????????????????lb.Items.Add("asdasdasd");
20?????????????????lb.Show();
21?????????????????lb.TabIndex?=?100;
22?????????????????lb.Location?=?tb.GetPositionFromCharIndex(tb.SelectionStart);
23?????????????????lb.Left?+=?10;
24?????????????????tb.Controls.Add(lb);
25?????????????}
26?????????}
當然,另外一面,如果創建ListBox,而又在RichTextBox?點擊了鼠標也去釋放。
1?????????void?rich_MouseClick(object?sender,?MouseEventArgs?e)
2?????????{
3?????????????RichTextBox?tb?=?(RichTextBox)sender;
4?????????????Control[]?c?=?tb.Controls.Find("mylb",?false);
5?????????????if?(c.Length?>?0)
6?????????????????((ListBox)c[0]).Dispose();
7?????????}
當然還得在Form1_Load里注冊事件
1?rich.MouseClick?+=?new?MouseEventHandler(rich_MouseClick);
然后設置ListBox?被選擇后用被選擇的關鍵字替換前文搜索到的字符。
下面我們來看看實現行號。
四、實現行號
這個是RichTextBox?唯一令我遺憾的地方,居然無法實現行號問題。為什么呢?我首先想到的是自己畫。用rich.CreateGraphics()來畫。但是,由于畫的時候發生在窗體被創建時,所以畫不成功,而被RichTextBox?本身的繪制給覆蓋了。
然后我選擇了在里面添加Label控件
?1????????????Label?l?=?new?Label();
?2?????????????l.Name?=?"l";
?3?????????????l.Top?=?0;
?4?????????????l.TextAlign?=?ContentAlignment.TopRight;
?5?????????????l.Width?=?40;
?6?????????????l.Text?=?"1";
?7?????????????l.Font?=?new?Font("宋體",?12,?(FontStyle.Regular));
?8?????????????l.Height?=?this.Height;
?9?????????????l.BackColor?=?Color.Gray;
10?????????????l.BorderStyle?=?BorderStyle.None;
11?????????????rich.Controls.Add(l);
12?
13?????????????rich.SelectionIndent?=?40;
?rich.SelectionIndent?=?40;是把光標對齊到左邊距40的位置,防止光標被Label覆蓋。
實現編號還不是太難。麻煩出在如何讓Lable能跟隨RichTextBox?的滾動條滾動。不說實現的 細節,我就假設,如果滾動條向上滾,那么Lable的Top屬性增加,反之則減少。但是,RichTextBox?居然無法對ScollBar進行監測。
根本每辦法知道滾動條滾動了多少位置,甚至都沒辦法知道滾動條滾動的方向。
嘗試去除滾動條,然后之間添加新的滾動條
?1?????????????VScrollBar?vs?=?new?VScrollBar();
?2?????????????//vs.Dock?=?DockStyle.Right;
?3?????????????vs.Name?=?"vs";
?4?????????????vs.Maximum?=?0;
?5?????????????vs.Minimum?=?0;
?6?????????????vs.MaximumSize?=?new?Size(0,0);
?7?????????????vs.Top?=?0;
?8?????????????vs.Left?=?rich.Parent.Width?-?100?-22;
?9?????????????vs.Height?=?rich.Parent.Height?-?100?-1;
10?????????????vs.Value?=?0;
11?????????????vs.Scroll?+=?new?ScrollEventHandler(vs_Scroll);
12?????????????
13?????????????rich.Controls.Add(vs);
但是非常難于實現同步滾動,位置很難控制。這個就是目前遇到的RichTextBox?的最大局限性了,非常遺憾,無法開發出這個功能。
birdshover
http://www.cnblogs.com/birdshover/
2007年1月30日
總結
以上是生活随笔為你收集整理的C#开发高亮语法编辑器(一)——TextBox ,RichTextBox的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oppo的sd卡在哪里打开_oppo的s
- 下一篇: python需要什么包装_python学