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

首先建立一个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>  

然后在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; }
            }  

        }
    }  
时间: 2024-10-16 15:38:00

【C#】【转】RichTextBox实现关键字自定义颜色显示(C#)的相关文章

Robot Framework 关键字自定义

关键字自定义有三种方法: 1.在自动化目录中右键-->New User Keyword 2.选中case中的步骤(可选多行),右键-->Extract Keyword 3.自己写模块,自定义方法,自动化项目引用模块,对应的模块中的方法就是一个个关键字了 方法1和2其实差不多,但没有方法3自由,在自动化的项目中一般都是方法混用的 要用关键字首先需要应用模块: 在directory和suite中都可以引用模块--library(py文件或者是本地python安装环境lib--sitepackage

WPF Toolkit AutoCompleteBox 实体类绑定 关键字自定义关联搜索匹配

原文:WPF Toolkit AutoCompleteBox 实体类绑定 关键字自定义关联搜索匹配 网上的例子都是零散的   翻阅了 很多篇文章后 再根据 自己项目的实际需求  整理出一个完整的 应用例子 汉字首字母全文匹配 提取绑定实体类相应的ID值 XAML <Window x:Class="WpfApp3.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quo

注解2 --- 自定义 Annotation --- 技术搬运工(尚硅谷)

定义新的 Annotation 类型使用 @interface 关键字 自定义注解自动继承了java.lang.annotation.Annotation接口 Annotation 的成员变量在 Annotation 定义中以无参数方法的形式来声明.其方法名和返回值定义了该成员的名字和类型.我们称为配置参数.类型只能是八种基本数据类型.String类型.Class类型.enum类型.Annotation类型.以上所有类型的数组. 可以在定义 Annotation 的成员变量时为其指定初始值, 指

Shell基础 - Bash基础功能

历史命令 history选项: -c 清空历史命令 -w 立即保存历史命令Linux 下输入过的历史命令,都会保存在根目录下的:~/root/.bash_history 文件中默认保存 1000 条,可在 /etc/profile 文件中修改环境变量!ser : 执行最后一条以 ser 开头的命令!! : 再次执行上一条命令 定义别名# alias vi = “vim” // 重启系统消失# unalias vi永久生效# vi /root/.bashrc 输出重定向标准输出重定向:命令 > 文

linux基础整理4

IP地址配置 1.setup工具 vi /etc/sysconfig/network-scripts/ifcfg-eth0 ONBOOT=yes service network restart 2.修改虚拟机连接方式为桥接 3.编辑-虚拟网络编辑器-vmnet0--桥接到有线网卡 4.UUID错误(针对复制镜像生效) vi/etc/sysconfig/network-scripts/ifcfg-eth0         删除MAC地址行 rm –rf/etc/udev/rules.d/70-pe

Bash常用快捷键基础(二)

3.输入重定向 #wc[选项] [文件名] 选项: -c    统计字节数 -w    统计单词数 -l     统计行数 命令<文件    把文件作为命令的输入 10.3.4  Bash基本功能-多命令顺序执行与管道符 1.多命令顺序执行   多命令执行符 格式 作用 : 命令1:命令2   多个命令顺序执行,命令之间没有任何逻辑联系  && 命令1&&命令2 逻辑与 当命令1正确执行,则命令2才会执行 当命令1执行不正确,则命令2不会执行   || 命令1||命令

linux 学习10 shell 基础

10.1 Shell概述 1.Shell是什么 ?Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动.挂起.停止甚至是编写一些程序. ?Shell还是一个功能相当强大的编程语言,易编写,易调试,灵活性较强.Shell是解释执行的脚本语言,在Shell中可以直接调用Linux系统命令. 2.Shell的分类 ?Bourne Shell:从1979起Unix就开始使用Bourne Shell,Bourne Shell的主文

Linux运维 第二阶段 (八)shell基础

Linux运维第二阶段(八)shell基础 一.shell的两种主要语法:Bourne家族(sh/ksh/bash/psh/zsh);C家族(csh/tcsh). 注:bash和zsh在不同程度上支持csh的语法. #vi  /etc/shells                 (可查询linux支持的shell) 二.1.#echo  -e|-n  输出内容 -e      可支持反斜线\控制的字符转换(\\,\a,\b,\c,\e,\f\,\n,\r,\t,\v,\0mmm,\xhh) -

【Linux】鸟哥的Linux私房菜基础学习篇整理(五)

1. type [-tpa] name:查看name命令是否为bash内置命令.参数:type:不加任何参数,type会显示出那么是外部命令还是bash的内置命令:-t:当加入-t参数时,type会通过如下关键字显示其意义: file:表示为外部命令 alias:表示为命名别名 builtin:表示为bash的内置命令-p:如果后面接的name为外置命令时,才会显示完整文件名:-a:会由PATH变量定义的路径中,将含有name的命令都列出来,包含别名. 2. unset name:取消变量名na