C#开发高亮语法编辑器(一)——TextBox ,RichTextBox

C#简单实现高亮语法编辑器(一)
         ——TextBox ,RichTextBox的局限性


一、RichTextBox基本设置
二、实现语法高亮
三、关键字提示
四、实现行号

就简单快速得开发文本编辑器TextBox 最为简单,大家用得也多,缺点是无法实现复杂的操作。RichTextBox虽然是则功能比它强大很多。

TextBox.gif
图 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日

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/549884.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言即时通讯软件源码,即时通讯软件源码-基于c语言即时通讯软件代码实现

我不知道哪种语言无关紧要。开源&#xff0c;我不知道该用什么。即时通讯软件源代码为JAVA语言对于即时通讯软件源代码最好是用C语言编写的&#xff0c;想学一下&#xff0c;感谢您即时通讯软件有什么。includewinscock2、h#includewinscock2、h#includesting。h#includewindow…

探讨继承与实现(二)

前文 探讨继承与实现&#xff08;一&#xff09; 根据双鱼座的提示已经更新。很不巧&#xff0c;我也是双鱼座的。由于水平有限&#xff0c;有什么不足还请大家指教。2007年2月1日 http://www.cnblogs.com/birdshover/目录&#xff1a;一、抽象的产生二、依赖抽象三、抽象的损…

实现android应用程序自动化测试的批处理脚本,简单入手移动端并发自动化测试:Appium+Robot+ 批处理脚本...

一、前言好久没写帖子&#xff0c;去年晋升为 leader 之后工作比较忙&#xff0c;去年为团队的产品建立了一轮的移动端(Android&iOS)的自动化测试&#xff0c;到今天为止跑了将近半年&#xff0c;前期感觉还行&#xff0c;但随着用例的增加&#xff0c;执行自动化脚本的时间…

Castle学习之一:安装与环境设置

第一步&#xff0c;当然是下载了。我本来下载的是Castle RC2的MSI安装文件&#xff0c;并通过SVN下载了Generator&#xff0c;但是安装后发现了一些问题&#xff08;主要是.net版本的问题&#xff09;&#xff0c;所以删除了之后&#xff0c;从SVN下载了全部最新的代码&#xf…

next按钮源码android,Android Edittext 软键盘输入法回车键改成下一步Next

软件盘中回车键默认功能是换行&#xff0c;但是有时候我们在Edittext中输完内容后点回车想要把焦点切到下一个Edittext继续输入&#xff0c;比如常见的登录页面&#xff0c;在输完用户名后&#xff0c;点回车调到输入密码输入框继续输入。示例代码代码很简单&#xff0c;如下所…

SQL SERVER 2005 T_SQL新的特性以及解决并发

一.修改语句的增强UPDATE test SET tname.WRITE(one hundred and two, 9, 3) WHERE tid 102在2005中增强了update方法&#xff0c;这是修改test表的列tname WRITE方法是把tname这个列中从字符串9开始 把3个长的字符串改为one hundred and two二、异常的捕获可以捕获过去会导致…

android跑分和ios,手机:苹果VS安卓 跑分不代表手机流畅度

原标题&#xff1a;手机&#xff1a;苹果VS安卓 跑分不代表手机流畅度在当前的国内手机市场中&#xff0c;有两个阵营&#xff1a;安卓和苹果。 安卓系统仍然是使用最多的系统。从最初的128M内存到当前的十多GB内存&#xff0c;安卓手机已得到迅速发展和更新。但总体而言&#…

余宏德:Sun所有的核心技术都是开放的

3月30日上午&#xff0c;“Sun 2007年媒体论坛”在香港举办。时值Sun公司成立25周年&#xff0c;因此本次活动备受大家关注。Sun公司大中华区管理层和技术专家与40家左右的媒体记者进行了面对面的讨论。本次活动的主题是“创新共享成长&#xff0d;为社会进步而创新”&#xff…

图示/白话 execve执行流程

转载于:https://www.cnblogs.com/image-eye/archive/2011/07/13/2105411.html

易企秀手机html5场景源码,【VIP源码】六月1日最新完美版易企秀微信场景源码

[v_notice]下面演示图为哥亲测截图&#xff0c;仅供参考&#xff0c;在这里下载的源码100%和演示截图一致[/v_notice]修补的首页&#xff1a;前台用户后台界面&#xff1a;场景制作界面&#xff1a;转场特效页面&#xff1a;特效增加&#xff1a;设计模板&#xff1a;制作预览页…

Effective C# 原则48:了解更多的工具和资源(译)

Effective C# 原则48&#xff1a;了解更多的工具和资源 Item 48: Learn About Tools and Resources 对于C#以及.Net来说这是激动人心的时候。这些工具目前还是比较新的&#xff0c;整个社区都在学习如何使用这些工具。一些资源可以帮助你提高你的知识&#xff0c;以及为.Net和…

计算机2013知识,【2013年计算机基础知识习题与答案(三)】- 环球网校

46.与十进制数128等值的二进制数是10000000.47.与十进制数217等值的二进制数是11011001.48.八进制数的基数为8&#xff0c;能用到的数字符号个数为8.49.十进制数38转换成八进制数是46.50.十进制数72转换成八进制数是110.51.与十进制数283等值的十六进制数是11B.52.与二进制数11…

上周回顾:艾妮闹春 Sun/HP高层人士震荡

进入4月&#xff0c;春暖花开。然而随着Vista首个漏洞“ANI”的到来&#xff0c;上周显然让许多人又紧张了一回。同样紧张的还有IT媒体的记者&#xff1a;周一一上班就传出Sun公司大中华区总裁余宏德和其他高管离职的消息&#xff0c;周五临下班HP中国总裁孙振耀又宣布“退休”…

计算机自带游戏如何删除,详细教你系统怎么删除游戏

很多时候&#xff0c;在我们安装系统就会自带一些游戏软件&#xff0c;但是我们不怎么感兴趣&#xff0c;放在那里有占用内存&#xff0c;只有将它们删除了&#xff0c;如何彻底删除windows系统自带的游戏蜘蛛纸牌呢&#xff1f;下面&#xff0c;就有系统之家小编来给大家讲解系…

win10创建新的计算机用户名和密码错误,Win10开机提示用户名或密码不正确现象的解决办法...

有用户遇到Win10开机提示用户名或密码不正确的问题&#xff0c;当你点击“确定(OK)”后欢迎屏幕上会出现两个相同的用户账户让你选择&#xff0c;让你不知道该选择哪一个&#xff0c;这个问题是什么原因&#xff1f;怎么解决呢。问题原因出现上述问题的原因可能是你在设置了Win…

删除计算机360云盘,win7系统怎么取消电脑右键保存到360云盘选项

在日常使用win7系统的时候&#xff0c;我们经常会用到右键菜单&#xff0c;可是有时候会遇到一些没有用的选项&#xff0c;比如保存到360云盘选项&#xff0c;如果不喜欢的话&#xff0c;要怎么取消电脑右键保存到360云盘选项呢&#xff1f;具体步骤如下。1、首先有这一项的都是…

网吧服务器RAID 0+1硬盘阵列组建图解

网吧服务器RAID 01硬盘阵列组建图解步小羽   2007年04月13日   来源&#xff1a;天下网吧联盟随着网吧规模扩大&#xff0c;网吧电脑数量也会相应增加&#xff0c;上网的顾客也随之增多&#xff0c;服务器硬盘数据存取的速度将会成为新的瓶颈&#xff0c;很多顾客开始投诉服务…

VXLAN实验

拓扑图&#xff1a; SPINE配置&#xff1a; hostname SPINE-1vdc SPINE-1 id 1 limit-resource vlan minimum 16 maximum 4094 limit-resource vrf minimum 2 maximum 4096 limit-resource port-channel minimum 0 maximum 511 limit-resource u4route-mem minimum 248 maximum…

VSTS For Testers读书笔记(5)

四、编辑WebTest3、添加提取规则和自定义提取规则添加提取规则1、当必须从特定页中捕获一部分数据并且供另一个页使用时&#xff0c;就需要用到提取规则。可以使用提取规则从响应中复制字符串&#xff0c;然后将字符串存储到上下文变量中&#xff0c;以供任何后续请求使用。通过…

html里面怎么ul加高度,div里面嵌套了ul,为什么div的高度小于ul高度

div高度见阴影部分ul高度见阴影部分实现的html代码如下&#xff1a;热门推荐css代码如下&#xff1a;.navBar {clear: both;width: 100%;border: solid;/*border-top: solid;*/border-bottom: solid;border-width: 1px;border-color: #dddddd;margin:0px;height: 1.5em;}.navBa…