首页 > 代码库 > RichTextBox着色与着色不闪

RichTextBox着色与着色不闪

近来写的一个数据查询分析器意外的快捷,不到两晚工夫就搞定了。完成度相当的高。当然少不了关键字着色,不过着色的代码来自的网上,看了一下感觉过多的循环

//文本框改变事件                int index = this.richTextBox1.SelectionStart;  //记录修改的位置                       string[] keystr ={ "select ", "from ", "where ", " and ", " or ", " order ", " by ", " desc ", " when ", " case ",  " then ", " end ", " on ", " in ", " is ", " as ", " else ", "left ", " join ", " not ", " null "," like "," exists " };            for (int i = 0; i < keystr.Length; i++)                this.getbunch(keystr[i], this.richTextBox1.Text, Color.Blue);public int getbunch(string p, string s,Color pColor) //给关键字上色        {            int cnt = 0; int M = p.Length; int N = s.Length;            char[] ss = s.ToCharArray(), pp = p.ToCharArray();            if (M > N) return 0;            for (int i = 0; i < N - M + 1; i++)            {                int j;                for (j = 0; j < M; j++)                {                    if (ss[i + j] != pp[j]) break;                }                if (j == p.Length)                {                    this.richTextBox1.Select(i, p.Length);                    this.richTextBox1.SelectionColor = pColor;                    cnt++;                }            }            return cnt;        }

且关键字的边界也没有处理好。于是重新组织了判断关键字的代码,总的流程是先记录所有关键字及其所用颜色。从头到到尾取出每一个单词着色,以下是主体代码

/// <summary>/// 着色/// </summary>public void RunColor(){    this.BeginUpdate();//停止绘制    //文本框改变事件        int lastIndex = this.SelectionStart;  //记录修改的位置        int index =0;    int wordStart=-1;//找到的单词开始位置    char[] text = this.Text.ToCharArray();//打散每一个字符    StringBuilder sb = new StringBuilder();    //尝试取出每一个单词    while(index<text.Length)    {        char chk = text[index];        if (WhiteSpaceChars.Contains(chk))//是否空白字符        {            if (wordStart >= 0)            {                //取出单词                string code = sb.ToString();                colorWords(code.ToLower(), wordStart);                wordStart = -1;            }            else            {                //空白字符,未找到词开头,不需作任何处理            }        }        else        {            //找到非空白字符            if (wordStart == -1)//找到词开头了。            {                sb = new StringBuilder();                wordStart = index;            }            sb.Append(chk);        }        index++;//下一字符    }    if (sb.Length > 0 && wordStart>=0)//最后一个词    {        string code = sb.ToString();        colorWords(code.ToLower(),wordStart);    }    this.Select(lastIndex, 0);  //返回修改的位置    this.SelectionColor = Color.Black;    this.EndUpdate();//恢复绘制事件            }

以下是完整的RichTextbox的代码,解决着色不闪。着色方法RunColor需要外部调用,控件不会自动着色。

public class MyRichTextBox : RichTextBox    {        //private class paintHelper : Control        //{        //    public void DefaultWndProc(ref Message m)        //    {        //        this.DefWndProc(ref m);        //    }        //}        private const int WM_PAINT = 0x000F;        private int lockPaint;        private bool needPaint;                //private paintHelper pHelp = new paintHelper();        public void BeginUpdate()        {                        lockPaint++;        }        public void EndUpdate()        {                        lockPaint--;            if (lockPaint <= 0)            {                lockPaint = 0;                if (needPaint)                {                    this.Refresh();                    needPaint = false;                }            }        }        protected override void WndProc(ref Message m)        {            switch (m.Msg)            {                case WM_PAINT:                                       if (lockPaint <= 0)                    {                        base.WndProc(ref m);                    }                    else                    {                        needPaint = true;                        //pHelp.DefaultWndProc(ref m);                    }                    return;            }            base.WndProc(ref m);        }                Dictionary<string, Color> words = new Dictionary<string, Color>();        /// <summary>        /// 设置字符颜色        /// </summary>        /// <param name="pWords">关键字</param>        /// <param name="pColor">所用颜色</param>        /// <param name="isKeyWord">真时,替换之前设置的颜色。否的话,如果已设置相关关键字,忽略该设置</param>        public void SetColorWord(IEnumerable<string> pWords, Color pColor,bool isKeyWord)        {            foreach (string one in pWords)            {                string low = one.ToLower();                if (words.ContainsKey(low))                {                    if (isKeyWord)                        words[low] = pColor;                }                else                {                    words.Add(low, pColor);                }            }        }               /// <summary>        /// 着色        /// </summary>        public void RunColor()        {            this.BeginUpdate();//停止绘制            //文本框改变事件                int lastIndex = this.SelectionStart;  //记录修改的位置                        int index =0;            int wordStart=-1;//单词的开始位置            char[] text = this.Text.ToCharArray();//打散每一个字符            StringBuilder sb = new StringBuilder();            //尝试取出每一个单词            while(index<text.Length)            {                char chk = text[index];                if (WhiteSpaceChars.Contains(chk))//是否空白字符                {                    if (wordStart >= 0)//空白字符,前面已找到单词的开始位置,这就是单词的结束了                    {                        //取出音词                        string code = sb.ToString();                        colorWords(code.ToLower(), wordStart);                        wordStart = -1;                    }                    else                    {                        //空白字符,未找到词开头,不需作任何处理                    }                }                else                {                    //找到非空白字符                    if (wordStart == -1)//找到词开头了。                    {                        sb = new StringBuilder();                        wordStart = index;                    }                    sb.Append(chk);                }                index++;//下一字符            }            if (sb.Length > 0 && wordStart>=0)//最后一个词            {                string code = sb.ToString();                colorWords(code.ToLower(),wordStart);            }            this.Select(lastIndex, 0);  //返回修改的位置            this.SelectionColor = Color.Black;            this.EndUpdate();//恢复绘制事件                    }        /// <summary>        /// 给单词着色,非关键字改为黑色        /// </summary>        /// <param name="pChkWord"></param>        /// <param name="pStart"></param>        private void colorWords(string pChkWord,int pStart)        {            this.Select(pStart, pChkWord.Length);            if (words.ContainsKey(pChkWord))                this.SelectionColor = words[pChkWord];            else                this.SelectionColor = Color.Black;        }        /// <summary>        /// 空白字符        /// </summary>        public static readonly char[] WhiteSpaceChars = new char[] { (char)0x00, (char)0x01, (char)0x02, (char)0x03, (char)0x04, (char)0x05,             (char)0x06, (char)0x07, (char)0x08, (char)0x09, (char)0x0a, (char)0x0b, (char)0x0c, (char)0x0d, (char)0x0e, (char)0x0f,             (char)0x10, (char)0x11, (char)0x12, (char)0x13, (char)0x14, (char)0x15, (char)0x16, (char)0x17, (char)0x18, (char)0x19, (char)0x20,            (char)0x1a, (char)0x1b, (char)0x1c, (char)0x1d, (char)0x1e, (char)0x1f, (char)0x7f, (char)0x85, (char)0x2028, (char)0x2029 };    }

 

RichTextBox着色与着色不闪