课设准备用WPF做一个写字板,打算能够代码高亮,结果发现WPF中的RichTextbox和WinForm里面的RichTextbox差别很大。不得不求助网络,在 郁闷的小胡子 的博客中发现了关键字高亮的一些代码。(http://www.cnblogs.com/xiaohuziHu/archive/2010/12/17/xiaohuzi.html)十分感谢他的分享。但是这段代码有些不尽人意的地方,在这里提出解决方案。
首先贴出和原版对应的类的代码吧~
1
public
void
ChangeColor(Color l, RichTextBox richBox,
string
keyword)
2 {
3 // 设置文字指针为Document初始位置
4 // richBox.Document.FlowDirection
5 TextPointer position = richBox.Document.ContentStart;
6 while (position != null )
7 {
8 // 向前搜索,需要内容为Text
9 if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
10 {
11 // 拿出Run的Text
12 string text = position.GetTextInRun(LogicalDirection.Forward);
13 // 可能包含多个keyword,做遍历查找
14 int index = 0 ;
15 index = text.IndexOf(keyword, 0 );
16 if (index != - 1 )
17 {
18 TextPointer start = position.GetPositionAtOffset(index);
19 TextPointer end = start.GetPositionAtOffset(keyword.Length);
20 position = selecta(l, richBox, keyword.Length, start, end);
21 }
22
23 }
24 // 文字指针向前偏移
25 position = position.GetNextContextPosition(LogicalDirection.Forward);
26
27 }
28 }
2 {
3 // 设置文字指针为Document初始位置
4 // richBox.Document.FlowDirection
5 TextPointer position = richBox.Document.ContentStart;
6 while (position != null )
7 {
8 // 向前搜索,需要内容为Text
9 if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
10 {
11 // 拿出Run的Text
12 string text = position.GetTextInRun(LogicalDirection.Forward);
13 // 可能包含多个keyword,做遍历查找
14 int index = 0 ;
15 index = text.IndexOf(keyword, 0 );
16 if (index != - 1 )
17 {
18 TextPointer start = position.GetPositionAtOffset(index);
19 TextPointer end = start.GetPositionAtOffset(keyword.Length);
20 position = selecta(l, richBox, keyword.Length, start, end);
21 }
22
23 }
24 // 文字指针向前偏移
25 position = position.GetNextContextPosition(LogicalDirection.Forward);
26
27 }
28 }
还有一个函数
1
public
TextPointer selecta(Color l,RichTextBox richTextBox1,
int
selectLength, TextPointer tpStart, TextPointer tpEnd)
2 {
3 TextRange range = richTextBox1.Selection;
4 range.Select(tpStart, tpEnd);
5 // 高亮选择
6
7 range.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(l));
8 range.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
9
10 return tpEnd.GetNextContextPosition(LogicalDirection.Forward);
11 }
2 {
3 TextRange range = richTextBox1.Selection;
4 range.Select(tpStart, tpEnd);
5 // 高亮选择
6
7 range.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(l));
8 range.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
9
10 return tpEnd.GetNextContextPosition(LogicalDirection.Forward);
11 }
这里解释一下为什么郁闷的小胡子会发现关键字只有部分高亮。这是因为在对关键字高亮的时候整个文档的结构也发生了变化,以前是一个Context包含文字的,但是现在由于有了高亮的关键字,这个时候文档的前半段自动变成一个Context,关键字是一个Context,然后后半段是一个Context。如图:
左边是原始状态,右边是当关键字高亮后的状态。其中圆矩框表示一个Context。
我的解决方案很简单,就是在高亮的Context之后重新赋值position,让其指向下一个Context即可。