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

本文介绍了一种在Visual Studio中实现C#代码语法高亮的方法。通过创建XML配置文件定义关键字及其颜色,并利用.NET Framework编写自定义解析器类,实现了对C#源代码的关键字识别与着色。
摘要由CSDN通过智能技术生成

首先建立一个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.Drawing;
using System.Runtime.InteropServices;
using HWND = System.IntPtr;

namespace WindowsFormsApplication2
{
    public partial 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>
         
        #region 组件设计器生成的代码
        /// <summary>
        /// 设计器支持所需的方法 - 不要使用代码编辑器 
        /// 修改此方法的内容。
        /// </summary>
      
        #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; }
        }


    }
}



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值