如何突出显示 RichTextBox 中的特定文本?
How to highlight specific text in a RichTextBox?
在 RichTextBox
控件中,我试图以红色突出显示特定文本作为正则表达式匹配的结果。
样本:
此文本语句工作正常并以红色阴影突出显示 'Deans':
select top 10 * from client where MailName='Deans'
此文本语句也可以正常工作并以红色阴影突出显示代码:
select top 10 * from client where MailName='De a ns'
但是这条语句失败了:
select top 10 * from client where MailName='Deans '
它失败了,因为单引号之间有 space,它在开始 TextRange at
的行上抛出异常
TextRange result = new TextRange(start, start.GetPositionAtOffset(word.Length));
例外说:
invalid parameter position 2.
请给我一个解决方案。我哪里出错了?
这是代码片段:
string StringFromRichTextBox(RichTextBox rtb)
{
TextRange textRange = new TextRange(rtb.Document.ContentStart,
rtb.Document.ContentEnd);
return textRange.Text;
}
private void TextChangedEventHandler(object sender, TextChangedEventArgs e)
{
TextRange documentRange = new TextRange(txtQueries.Document.ContentStart, txtQueries.Document.ContentEnd);
documentRange.ClearAllProperties();
MatchCollection match = Regex.Matches(StringFromRichTextBox(txtQueries), @"'([^']*)'");
for (int z = 0; z < match.Count; z++)
{
CheckKeyword(documentRange, match[z].ToString().Trim());
}
}
private void CheckKeyword(TextRange textRange, string word)
{
//txtQueries.TextChanged -= this.TextChangedEventHandler;
if (textRange.Text.Contains(word))
{
int offset = textRange.Text.IndexOf(word);
if (offset < 0)
{
return;
}// Not found
else
{
// Try to select the text as a contiguous range
for (TextPointer start = textRange.Start.GetPositionAtOffset(offset); start != textRange.End; start = start.GetPositionAtOffset(1))
{
try
{
TextRange result = new TextRange(start, start.GetPositionAtOffset(word.Length));
if (result != null && result.Text == word)
{
result.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Red));
break;
}
}
catch(Exception ex)
{
throw new Exception(ex.Message);
}
}
}
}
//txtQueries.TextChanged += this.TextChangedEventHandler;
}
错误信息:
Value cannot be null.
Parameter name: position2
at System.Windows.Documents.TextRange..ctor(TextPointer position1, TextPointer position2)
解决方案 :: 向偏移长度添加 4 以说明 richtextbox 中 space 出现的特殊不可见字符。
var length = word.Length;
// Try to select the text as a contiguous range
for (TextPointer start = textRange.Start.GetPositionAtOffset(offset); start != textRange.End; start = start.GetPositionAtOffset(1))
{
try
{
TextRange result = new TextRange(start, start.GetPositionAtOffset(word.Contains(" ") ? word.Length + 4: word.Length)); //Added 4 to the offset length to account for special invisible characters coming up with space in richtext box
if (result.Text.Trim() == word.Trim())
{
result.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Red));
break;
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
我在解决这个问题时也遇到了很多麻烦!在使用 GetPositionAtOffset
进行了大量 wtf 之后,我想出了这种方法来在 RichTextBox
:
中搜索时获得准确的 TextPointer
s
public static TextRange FindStringRangeFromPosition(TextPointer position, string str) {
//what makes this work is checking the PointerContext so you avoid the markup characters
while (position != null) {
if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text) {
string textRun = position.GetTextInRun(LogicalDirection.Forward);
// Find the starting index of any substring that matches "str".
int indexInRun = textRun.IndexOf(str);
if (indexInRun >= 0) {
//since we KNOW we're in a text section we can find the endPointer by the str.Length now
return new TextRange(position.GetPositionAtOffset(indexInRun), position.GetPositionAtOffset(indexInRun + str.Length));
}
}
position = position.GetNextContextPosition(LogicalDirection.Forward);
}
// position will be null if "str" is not found.
return null;
}
在 RichTextBox
控件中,我试图以红色突出显示特定文本作为正则表达式匹配的结果。
样本:
此文本语句工作正常并以红色阴影突出显示 'Deans':
select top 10 * from client where MailName='Deans'
此文本语句也可以正常工作并以红色阴影突出显示代码:
select top 10 * from client where MailName='De a ns'
但是这条语句失败了:
select top 10 * from client where MailName='Deans '
它失败了,因为单引号之间有 space,它在开始 TextRange at
的行上抛出异常TextRange result = new TextRange(start, start.GetPositionAtOffset(word.Length));
例外说:
invalid parameter position 2.
请给我一个解决方案。我哪里出错了?
这是代码片段:
string StringFromRichTextBox(RichTextBox rtb)
{
TextRange textRange = new TextRange(rtb.Document.ContentStart,
rtb.Document.ContentEnd);
return textRange.Text;
}
private void TextChangedEventHandler(object sender, TextChangedEventArgs e)
{
TextRange documentRange = new TextRange(txtQueries.Document.ContentStart, txtQueries.Document.ContentEnd);
documentRange.ClearAllProperties();
MatchCollection match = Regex.Matches(StringFromRichTextBox(txtQueries), @"'([^']*)'");
for (int z = 0; z < match.Count; z++)
{
CheckKeyword(documentRange, match[z].ToString().Trim());
}
}
private void CheckKeyword(TextRange textRange, string word)
{
//txtQueries.TextChanged -= this.TextChangedEventHandler;
if (textRange.Text.Contains(word))
{
int offset = textRange.Text.IndexOf(word);
if (offset < 0)
{
return;
}// Not found
else
{
// Try to select the text as a contiguous range
for (TextPointer start = textRange.Start.GetPositionAtOffset(offset); start != textRange.End; start = start.GetPositionAtOffset(1))
{
try
{
TextRange result = new TextRange(start, start.GetPositionAtOffset(word.Length));
if (result != null && result.Text == word)
{
result.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Red));
break;
}
}
catch(Exception ex)
{
throw new Exception(ex.Message);
}
}
}
}
//txtQueries.TextChanged += this.TextChangedEventHandler;
}
错误信息:
Value cannot be null. Parameter name: position2 at System.Windows.Documents.TextRange..ctor(TextPointer position1, TextPointer position2)
解决方案 :: 向偏移长度添加 4 以说明 richtextbox 中 space 出现的特殊不可见字符。
var length = word.Length;
// Try to select the text as a contiguous range
for (TextPointer start = textRange.Start.GetPositionAtOffset(offset); start != textRange.End; start = start.GetPositionAtOffset(1))
{
try
{
TextRange result = new TextRange(start, start.GetPositionAtOffset(word.Contains(" ") ? word.Length + 4: word.Length)); //Added 4 to the offset length to account for special invisible characters coming up with space in richtext box
if (result.Text.Trim() == word.Trim())
{
result.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Red));
break;
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
我在解决这个问题时也遇到了很多麻烦!在使用 GetPositionAtOffset
进行了大量 wtf 之后,我想出了这种方法来在 RichTextBox
:
TextPointer
s
public static TextRange FindStringRangeFromPosition(TextPointer position, string str) {
//what makes this work is checking the PointerContext so you avoid the markup characters
while (position != null) {
if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text) {
string textRun = position.GetTextInRun(LogicalDirection.Forward);
// Find the starting index of any substring that matches "str".
int indexInRun = textRun.IndexOf(str);
if (indexInRun >= 0) {
//since we KNOW we're in a text section we can find the endPointer by the str.Length now
return new TextRange(position.GetPositionAtOffset(indexInRun), position.GetPositionAtOffset(indexInRun + str.Length));
}
}
position = position.GetNextContextPosition(LogicalDirection.Forward);
}
// position will be null if "str" is not found.
return null;
}