RichTextBox实现关键字自定义颜色显示(C#)

简介: 现在的很多编辑工具都能实现代码中关键字的高亮显示,自己一时好玩也就随便写了一个: 首先建立一个XML文件:csharp.

现在的很多编辑工具都能实现代码中关键字的高亮显示,自己一时好玩也就随便写了一个:

首先建立一个XML文件:csharp.xml

<?xml version="1.0" encoding="utf-8" ?>
<definition name="C#" caseSensitive="true">
<word color="BLUE">private</word>
<word color="BLUE">protected</word>
<word color="BLUE">public</word>
<word color="BLUE">namespace</word>
<word color="BLUE">class</word>
<word color="BLUE">for</word>
<word color="BLUE">if</word>
<word color="BLUE">else</word>
<word color="BLUE">while</word>
<word color="BLUE">switch</word>
<word color="BLUE">case</word>
<word color="BLUE">using</word>
<word color="BLUE">get</word>
<word color="BLUE">return</word>
<word color="BLUE">null</word>
<word color="BLUE">void</word>
<word color="BLUE">int</word>
<word color="BLUE">string</word>
<word color="BLUE">float</word>
<word color="BLUE">char</word>
<word color="BLUE">this</word>
<word color="BLUE">set</word>
<word color="BLUE">new</word>
<word color="BLUE">true</word>
<word color="BLUE">false</word>
<word color="BLUE">const</word>
<word color="BLUE">static</word>
<word color="BLUE">internal</word>
<word color="BLUE">extends</word>
<word color="BLUE">super</word>
<word color="BLUE">import</word>
<word color="BLUE">default</word>
<word color="BLUE">break</word>
<word color="BLUE">try</word>
<word color="BLUE">catch</word>
<word color="BLUE">finally</word>
<word color="CadetBlue">Main</word>
<word color="CadetBlue">WriteLine</word>
<word color="CadetBlue">Console</word>
<word color="CadetBlue">WriteLine</word>
<word color="DarkOrange">;</word>
<register>printf</register>
</definition>

其中color指定了该关键字的颜色.

然后在VS中新建一工程,添加下面的这个类:

using System;
using System.Xml;
using System.IO;
using System.Collections;
using System.Reflection;
using System.Drawing;

namespace WindowsApplication1
{

public class Parser
{
private XmlDocument xd=null;
private ArrayList al=null; //对xml流解析后,会把每一个关键字字符串放入这个容器中
private bool caseSensitive=false; //记录当前语言大小写敏感否
private ArrayList cl=null;//对xml流解析后,把每一个C关键字颜色保留



internal Parser(SyntaxEditor.Languages language) //构造函数接受一个枚举变量
{
Assembly asm
= Assembly.GetExecutingAssembly();
string filename="";
switch(language) //取得xml文件名
{
case SyntaxEditor.Languages.CSHARP:
filename
="csharp.xml";
break;
case SyntaxEditor.Languages.JSHARP:
filename
="jsharp.xml";
break;
case SyntaxEditor.Languages.SQL:
filename
="sql.xml";
break;
case SyntaxEditor.Languages.VBSCRIPT:
filename
="vbscript.xml";
break;
default:
break;
}

StreamReader reader
= new StreamReader(filename,
System.Text.Encoding.UTF8
);
//下面的代码解析xml流

xd
=new XmlDocument();
xd.Load(reader);

al
=new ArrayList();
cl
=new ArrayList();
XmlElement root
=xd.DocumentElement;

XmlNodeList xnl
=root.SelectNodes("/definition/word");
for(int i=0;i<xnl.Count;i++)
{
al.Add(xnl[i].ChildNodes[
0].Value); //将关键子收集到al
cl.Add(xnl[i].Attributes["color"].Value);//收集关键字的颜色

}
//检测是否判断大小写
this.caseSensitive=bool.Parse(root.Attributes["caseSensitive"].Value);

}

public Color IsKeyWord(string word ) //判断字符串是否为关键字
{

for(int i=0;i<al.Count;i++)
{
if(string.Compare(word,al[i].ToString(),!caseSensitive)==0)
{
string ColorTemp=(cl[i].ToString()!=string.Empty?cl[i].ToString():"Black");
Color c;
try
{
c
=Color.FromName(ColorTemp);
}
catch (Exception e)
{
c
=Color.Black;
}
return c;
}
}

return Color.Black;

}

}
}

 

然后新建一用户控件继承RichTextBox

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using HWND = System.IntPtr;

namespace WindowsApplication1
{
/// <summary>
/// SyntaxEditor 的摘要说明。
/// </summary>
public class SyntaxEditor :System.Windows.Forms.RichTextBox
{
/// <summary>
/// 必需的设计器变量。

/// </summary>
private System.ComponentModel.Container components = null;
int line;
private Parser parser;
/// <summary>
/// 必需的设计器变量。
/// </summary>
//使用win32api:SendMessage来防止控件着色时的闪烁现象
[DllImport("user32")] private static extern int SendMessage(HWND hwnd, int wMsg, int wParam, IntPtr lParam);
private const int WM_SETREDRAW = 0xB;
public SyntaxEditor()
{
// 该调用是 Windows.Forms 窗体设计器所必需的。
InitializeComponent();
base.WordWrap=false;
// TODO: 在 InitComponent 调用后添加任何初始化


}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器
/// 修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.Name = "SyntaxEditor";

}
#endregion
//重写基类的OnTextChanged方法。为了提高效率,程序是对当前文本插入点所在行进行扫描,
//以空格为分割符,判断每个单词是否为关键字,并进行着色。
protected override void OnTextChanged(EventArgs e)
{
if(base.Text!="")
{
int selectStart=base.SelectionStart;
line
=base.GetLineFromCharIndex(selectStart);
string lineStr=base.Lines[line];
int linestart=0;
for(int i=0;i<line;i++)
{
linestart
+=base.Lines[i].Length+1;
}

SendMessage(
base.Handle, WM_SETREDRAW, 0, IntPtr.Zero);

base.SelectionStart=linestart;
base.SelectionLength=lineStr.Length;
base.SelectionColor=Color.Black;
base.SelectionStart=selectStart;
base.SelectionLength=0;

//对一行字符串用空格或者.分开
string[] words=lineStr.Split(new char[]{' ','.','/n','(',')','}','{','"','[',']'});
parser
=new Parser(this.language);

for(int i=0;i<words.Length;i++)//一个字符段一个字符段来判断
{

//判断是否是程序保留字 是的话高亮显示
if(parser.IsKeyWord(words[i])!=Color.Empty)
{
int length=0;
for(int j=0;j<i;j++)
{
length
+=words[j].Length;
}
length
+=i;
int index=lineStr.IndexOf(words[i],length);


base.SelectionStart=linestart+index;
base.SelectionLength=words[i].Length;
//base.SelectionFont
base.SelectionColor=parser.IsKeyWord(words[i]);


base.SelectionStart=selectStart;
base.SelectionLength=0;
base.SelectionColor=Color.Black;
}


}
SendMessage(
base.Handle, WM_SETREDRAW, 1, IntPtr.Zero);
base.Refresh();
}
base.OnTextChanged (e);
}

public new bool WordWrap
{
get{return base.WordWrap;}
set{ base.WordWrap=value;}
}

public enum Languages
{
SQL,
VBSCRIPT,
CSHARP,
JSHARP
}

private Languages language=Languages.CSHARP;

public Languages Language
{
get{return this.language;}
set{this.language=value;}
}

}
}

 

这个时候你只要保证XML文件和exe或者数据集(如果你打算这样做)在同一个目录就可以了,看看吧下面就是测试效果:

呵呵 很简单哦,看样子写个C语言编辑环境也不是很难哦 呵呵~

我尝试去掉API在MONO上面编译,可惜MONO并没有支持RichTextBox控件,既然只能在Win上面运行,所以还是加上API好了,可以减少屏幕闪动感觉.

目录
相关文章
|
1月前
|
C#
30.C# 关键字 this初步学习
30.C# 关键字 this初步学习
15 1
|
1月前
|
C#
28.c#关键字base初步学习
28.c#关键字base初步学习
11 0
|
1月前
|
C#
27.c#关键字sealed修饰类
27.c#关键字sealed修饰类
12 0
|
2月前
|
SQL 开发框架 .NET
EntityFramework数据持久化复习资料3、C#拓展方法与yield关键字使用
EntityFramework数据持久化复习资料3、C#拓展方法与yield关键字使用
21 0
|
3月前
|
开发框架 .NET 编译器
C# 9.0中的静态匿名函数:引入static关键字的新用法
【1月更文挑战第15天】C# 9.0为匿名函数带来了一个新的修饰符static,允许开发者明确指定匿名函数不会捕获其包含作用域中的任何变量。这一特性增强了代码的性能和可读性,同时减少了因不小心捕获变量而导致的潜在错误。本文将详细探讨C# 9.0中静态匿名函数的语法、使用场景以及它们如何影响代码的性能和安全性。
|
1月前
|
存储 Java C++
31.C#:关键字static
31.C#:关键字static
15 1
|
1月前
|
C#
29.C#关键字throw初步学习
29.C#关键字throw初步学习
16 0
|
2月前
|
存储 编译器 C#
C#关键字常见面试题
C#关键字常见面试题
|
7月前
|
存储 编译器 C#
C#关键字相关面试题
C#关键字相关面试题
|
3月前
|
C# 数据安全/隐私保护 开发者
C# 9.0中的Init关键字:Init-only Setters的新篇章
【1月更文挑战第12天】本文介绍了C# 9.0中引入的Init关键字,该关键字允许创建仅在对象初始化时可设置属性的setter。通过Init-only setters,开发者能够更加灵活地控制对象属性的赋值时机,提高代码的可维护性和安全性。文章详细解释了Init关键字的使用方法、适用场景以及与传统setter的区别,并探讨了其在实际开发中的潜在影响。