• 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 };
        }
  • 相关阅读:
    C#代码常用技巧
    MVC
    json类型
    android 上传二进制文件的两种方式
    BroadcastReceiver 使用goAsync 执行异步操作
    android组件间通信又一种方式
    Android BLE基础框架使用详解
    Android BLE设备蓝牙通信框架BluetoothKit
    android studio ndk开发总结
    jni c基础总结
  • 原文地址:https://www.cnblogs.com/kevin-Y/p/5897449.html
Copyright © 2020-2023  润新知