基于WPF RichTextBox的编辑器(关键字高亮着色)

  近来,由于某个项目的需求,朋友托我做了个数据库小助手,功能很简单,主要是通过这个工具将数据表结构以HTML或者XML文件方式导出。

  可是做出来后,觉得这个工具功能太过简单了,于是就想着添加些功能上去,如查询显示数据库里的视图和存储过程等,如下图所示:

         我是用RichTextBox空间来显示存储过程的,不过在RichTextBox上显示的过于直白,关键没有着色,看上去觉得不怎么好看,而且很烦人。

         于是我想:RichTextBox能不能实现关键字高亮着色呢?

         如果是在WinForm中很简单(网上搜的):

        

代码
private void HilightRichText(RichTextBox control, string hilightString)
{
int nSelectStart = control.SelectionStart;
int nSelectLength = control.SelectionLength;
int nIndex = 0;
while (nIndex < control.Text.Length)
{
nIndex
= control.Find(hilightString, nIndex, RichTextBoxFinds.WholeWord);
if (nIndex < 0)
{
break;
}
control.Select(nIndex, hilightString.Length);
control.SelectionColor
= Color.Red;
nIndex
+= hilightString.Length;
}
control.Select(nSelectStart, nSelectLength);
}

          可是,在WPF中RichTextBox没有Find函数 ,也没用SelectionColor等函数,怎么办?

          于是我再翻过来,在MSDN上看看RichTextBox的结构,发现了RichTextBox内容是基于Document.FlowDirection的,可以通过TextPointer来确定要着色关键字的位置,然后在TextRange里的ApplyPropertyValue方法可以修改颜色。

            如下代码:

代码
public void ChangeColor(string l, RichTextBox richBox, string keyword)
{

//设置文字指针为Document初始位置
// richBox.Document.FlowDirection
TextPointer position = richBox.Document.ContentStart;
while (position != null)
{
//向前搜索,需要内容为Text
if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
{
//拿出Run的Text
string text = position.GetTextInRun(LogicalDirection.Forward);
//可能包含多个keyword,做遍历查找
int index = 0;
while (index < text.Length)
{
index
= text.IndexOf(keyword, index);
// MessageBox.Show(index.ToString());
if (index == -1)
{
break;
}
else
{
//添加为新的Range
TextPointer start = position.GetPositionAtOffset(index);
TextPointer end
= start.GetPositionAtOffset(keyword.Length);
TextPointer end1
= start.GetPositionAtOffset(index + keyword.Length);
selecta(l,richBox,keyword.Length, start, end);

index
+= keyword.Length;
}
}
}
//文字指针向前偏移
position = position.GetNextContextPosition(LogicalDirection.Forward);
}

}

               其中,改变关键字颜色的函数:

 

代码
public void selecta(string l,RichTextBox richTextBox1, int selectLength, TextPointer tpStart, TextPointer tpOffset)
{
TextRange range
= richTextBox1.Selection;
range.Select(tpStart, tpOffset);

//高亮选择
if(l=="blue"){
range.ApplyPropertyValue(TextElement.ForegroundProperty,
new SolidColorBrush(Colors.Blue));
range.ApplyPropertyValue(TextElement.FontWeightProperty,
FontWeights.Bold);
}
TextPointer position
= richTextBox1.Document.ContentStart;
TextPointer start
= position.GetPositionAtOffset(2);
TextPointer end
= richTextBox1.Document.ContentEnd;
TextRange range1
= richTextBox1.Selection;
range1.Select(end, end);
range1.ApplyPropertyValue(TextElement.ForegroundProperty,
new SolidColorBrush(Colors.Black));
}

           再定义个关键字数组:

           

代码
public string[] GetBlueKeyWords() // List from endelsebegin
{//union all @ as varchar [ ] .column_id sys.indexes sys.index_columns
string[] res = {"ADD","EXISTS","PRECISION","ALL","EXIT","PRIMARY","ALTER","EXTERNAL",
"PRINT","FETCH","PROC","ANY","FILE","PROCEDURE","AS","FILLFACTOR",
"PUBLIC","ASC","FOR","RAISERROR","AUTHORIZATION","FOREIGN","READ","BACKUP",
"FREETEXT","READTEXT","BEGIN","FREETEXTTABLE","RECONFIGURE","BETWEEN","FROM","from",
"REFERENCES","BREAK","FULL","REPLICATION","BROWSE","FUNCTION","RESTORE",
"BULK","GOTO","RESTRICT","BY","GRANT","RETURN","CASCADE","GROUP","REVERT",
"CASE","HAVING","REVOKE","CHECK","HOLDLOCK","RIGHT","CHECKPOINT","IDENTITY",
"ROLLBACK","CLOSE","IDENTITY_INSERT","ROWCOUNT","CLUSTERED","IDENTITYCOL",
"ROWGUIDCOL","COALESCE","IF","RULE","COLLATE","IN","SAVE","COLUMN","INDEX",
"SCHEMA","COMMIT","INNER","SECURITYAUDIT","COMPUTE","INSERT","SELECT",
"CONSTRAINT","INTERSECT","SESSION_USER","CONTAINS","INTO","SET","CONTAINSTABLE",
"SETUSER","CONTINUE","JOIN","SHUTDOWN","CONVERT","KEY","SOME","CREATE",
"KILL","STATISTICS","CROSS","LEFT","SYSTEM_USER","CURRENT","LIKE","TABLE",
"CURRENT_DATE","LINENO","TABLESAMPLE","CURRENT_TIME","LOAD","TEXTSIZE",
"CURRENT_TIMESTAMP","MERGE","THEN","CURRENT_USER","NATIONAL","TO","CURSOR",
"NOCHECK","TOP","DATABASE","NONCLUSTERED","TRAN","DBCC","NOT","TRANSACTION",
"DEALLOCATE","NULL","TRIGGER","DECLARE","NULLIF","TRUNCATE","DEFAULT","OF",
"TSEQUAL","DELETE","OFF","UNION","DENY","OFFSETS","UNIQUE","DESC", "ON",
"UNPIVOT","DISK","OPEN","UPDATE","DISTINCT","OPENDATASOURCE","UPDATETEXT",
"DISTRIBUTED","OPENQUERY","USE","DOUBLE","OPENROWSET","USER","DROP","OPENXML",
"VALUES","DUMP","OPTION","VARYING","ELSE","OR","VIEW","END","ORDER","WAITFOR",
"ERRLVL","OUTER","WHEN","ESCAPE","OVER","WHERE","EXCEPT","PERCENT","WHILE",
"EXEC","PIVOT","WITH","EXECUTE","PLAN","WRITETEXT", "GO", "ANSI_NULLS",
"NOCOUNT", "QUOTED_IDENTIFIER", "master","select","add","exists","precision","all","exit","primary","alter","external",
"print","fetch","proc","any","file","procedure","as","fillfactor",
"public","asc","for","raiserror","authorization","foreign","read","backup",
"freetext","readtext","begin","freetexttable","reconfigure","between","from","from",
"references","break","full","replication","browse","function","restore",
"bulk","goto","restrict","by","grant","return","cascade","group","revert",
"case","having","revoke","check","holdlock","right","checkpoint","identity",
"rollback","close","identity_insert","rowcount","clustered","identitycol",
"rowguidcol","coalesce","if","rule","collate","in","save","column","index",
"schema","commit","inner","securityaudit","compute","insert","select",
"constraint","intersect","session_user","contains","into","set","containstable",
"setuser","continue","join","shutdown","convert","key","some","create",
"kill","statistics","cross","left","system_user","current","like","table",
"current_date","lineno","tablesample","current_time","load","textsize",
"current_timestamp","merge","then","current_user","national","to","cursor",
"nocheck","top","database","nonclustered","tran","dbcc","not","transaction",
"deallocate","null","trigger","declare","nullif","truncate","default","of",
"tsequal","delete","off","union","deny","offsets","unique","desc", "on",
"unpivot","disk","open","update","distinct","opendatasource","updatetext",
"distributed","openquery","use","double","openrowset","user","drop","openxml",
"values","dump","option","varying","else","or","view","end","order","waitfor",
"errlvl","outer","when","escape","over","where","except","percent","while",
"exec","pivot","with","execute","plan","writetext", "go", "ansi_nulls",
"nocount", "quoted_identifier"};

return res;
}

              在Load代码中添加:

 

 

foreach (string s in GetBlueKeyWords())
{
ChangeColor(
"blue", tx, s);//tx是RichTextBox控件名字
}

 

              我想这样就差不多OK了吧?于是运行下看看:

         我晕!!!怎么颜色变得不怎么彻底?是怎么回事?郁闷了,辛苦了会儿,没想到还是失败了.....

         还是得改改啊(待续)......

         (各位朋友也可以帮改改)

posted on 2010-12-17 11:23  郁闷的小胡子  阅读(5397)  评论(3编辑  收藏  举报

导航