近来写的一个数据查询分析器意外的快捷,不到两晚工夫就搞定了。完成度相当的高。当然少不了关键字着色,不过着色的代码来自的网上,看了一下感觉过多的循环
//文本框改变事件
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 = ; i < keystr.Length; i++)
this.getbunch(keystr[i], this.richTextBox1.Text, Color.Blue); public int getbunch(string p, string s,Color pColor) //给关键字上色
{
int cnt = ; int M = p.Length; int N = s.Length;
char[] ss = s.ToCharArray(), pp = p.ToCharArray();
if (M > N) return ;
for (int i = ; i < N - M + ; i++)
{
int j;
for (j = ; 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 =;
int wordStart=-;//找到的单词开始位置
char[] text = this.Text.ToCharArray();//打散每一个字符
StringBuilder sb = new StringBuilder();
//尝试取出每一个单词
while(index<text.Length)
{
char chk = text[index];
if (WhiteSpaceChars.Contains(chk))//是否空白字符
{
if (wordStart >= )
{
//取出单词
string code = sb.ToString();
colorWords(code.ToLower(), wordStart);
wordStart = -;
}
else
{
//空白字符,未找到词开头,不需作任何处理
}
}
else
{
//找到非空白字符
if (wordStart == -)//找到词开头了。
{
sb = new StringBuilder();
wordStart = index;
}
sb.Append(chk);
}
index++;//下一字符
}
if (sb.Length > && wordStart>=)//最后一个词
{
string code = sb.ToString();
colorWords(code.ToLower(),wordStart);
}
this.Select(lastIndex, ); //返回修改的位置
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 <= )
{
lockPaint = ;
if (needPaint)
{
this.Refresh();
needPaint = false;
}
}
} protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_PAINT:
if (lockPaint <= )
{
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 =;
int wordStart=-;//单词的开始位置
char[] text = this.Text.ToCharArray();//打散每一个字符
StringBuilder sb = new StringBuilder();
//尝试取出每一个单词
while(index<text.Length)
{
char chk = text[index];
if (WhiteSpaceChars.Contains(chk))//是否空白字符
{
if (wordStart >= )//空白字符,前面已找到单词的开始位置,这就是单词的结束了
{
//取出音词
string code = sb.ToString();
colorWords(code.ToLower(), wordStart);
wordStart = -;
}
else
{
//空白字符,未找到词开头,不需作任何处理
}
}
else
{
//找到非空白字符
if (wordStart == -)//找到词开头了。
{
sb = new StringBuilder();
wordStart = index;
}
sb.Append(chk);
}
index++;//下一字符
}
if (sb.Length > && wordStart>=)//最后一个词
{
string code = sb.ToString();
colorWords(code.ToLower(),wordStart);
}
this.Select(lastIndex, ); //返回修改的位置
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 };
}