近来写的一个数据查询分析器意外的快捷,不到两晚工夫就搞定了。完成度相当的高。当然少不了关键字着色,不过着色的代码来自的网上,看了一下感觉过多的循环
//文本框改变事件 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 }; }
时间: 2024-10-06 01:41:49