C# 突出显示FlowDocument中的部分文本
我想根据搜索结果突出显示C# 突出显示FlowDocument中的部分文本,c#,wpf,highlight,flowdocument,C#,Wpf,Highlight,Flowdocument,我想根据搜索结果突出显示FlowDocument中的部分文本。我所做的是获取搜索词出现在流程文档文本中的索引,然后在文本范围上应用背景色,从找到的索引开始,以找到的索引+搜索词长度结束 TextRange content = new TextRange(myFlowDocument.ContentStart, myFlowDocument.ContentEnd); List<int> highlights = Ge
FlowDocument
中的部分文本。我所做的是获取搜索词出现在流程文档
文本中的索引,然后在文本范围上应用背景色,从找到的索引开始,以找到的索引+搜索词长度结束
TextRange content = new TextRange(myFlowDocument.ContentStart,
myFlowDocument.ContentEnd);
List<int> highlights = GetHighlights(content.Text, search);
foreach (int index in highlights)
{
var start = myFlowDocument.ContentStart;
var startPos = start.GetPositionAtOffset(index);
var endPos = start.GetPositionAtOffset(index + search.Length);
var textRange = new TextRange(startPos, endPos);
textRange.ApplyPropertyValue(TextElement.BackgroundProperty,
new SolidColorBrush(Colors.Yellow));
}
TextRange newRange = new TextRange(myFlowDocument.ContentStart,
newDocument.ContentEnd);
FlowDocument fd = (FlowDocument)XamlReader.Parse(newRange.Text);
TextRange content=new TextRange(myFlowDocument.ContentStart,
myFlowDocument.ContentEnd);
List highlights=GetHighlights(content.Text,search);
foreach(突出显示中的int索引)
{
var start=myFlowDocument.ContentStart;
var startPos=start.GetPositionAtOffset(索引);
var endPos=start.GetPositionAtOffset(index+search.Length);
var textRange=新的textRange(起始位置、结束位置);
textRange.ApplyPropertyValue(TextElement.BackgroundProperty,
新的SolidColorBrush(Colors.Yellow));
}
TextRange newRange=新的TextRange(myFlowDocument.ContentStart,
newDocument.ContentEnd);
FlowDocument fd=(FlowDocument)XamlReader.Parse(newRange.Text);
问题是,我正在搜索文档文本中的索引,但当我返回FlowDocument
时,添加了xaml标记,并且我看到突出显示被移动。
如何修复它?您需要使用
GetNextContextPosition(LogicalDirection.Forward)
进行迭代,并获取TextPointer
,将此指针与前面的TextPointer
一起使用以构造TextRange
。在此TextRange
上,您可以应用您的逻辑
您不能使用FlowDocument
中的单个文本范围来搜索文本<代码>流程文档不仅仅是文本:
private void Button_Click(object sender, RoutedEventArgs e)
{
String search = this.content.Text;
TextPointer text = doc.ContentStart;
while (true)
{
TextPointer next = text.GetNextContextPosition(LogicalDirection.Forward);
if (next == null)
{
break;
}
TextRange txt = new TextRange(text, next);
int indx = txt.Text.IndexOf(search);
if (indx > 0)
{
TextPointer sta = text.GetPositionAtOffset(indx);
TextPointer end = text.GetPositionAtOffset(indx + search.Length);
TextRange textR = new TextRange(sta, end);
textR.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Colors.Yellow));
}
text = next;
}
}
更新:
它并非始终有效,例如,如果您有列表,则特殊字符(\t)由IndexOf
计数,但GetPositionAtOffset
不将其计入:
• ListItem 1
• ListItem 2
• ListItem 3
这一行:
int indx = txt.Text.IndexOf(search);
可替换为:
int indx = Regex.Replace(txt.Text,
"[^a-zA-Z0-9_.]+", "", RegexOptions.Compiled).IndexOf(search);
最后,受user007答案的启发,在做了一些修改后,我设法突出显示了FlowDocument中出现的所有字符串。这是我的密码:
for (TextPointer position = newDocument.ContentStart;
position != null && position.CompareTo(newDocument.ContentEnd) <= 0;
position = position.GetNextContextPosition(LogicalDirection.Forward))
{
if (position.CompareTo(newDocument.ContentEnd) == 0)
{
return newDocument;
}
String textRun = position.GetTextInRun(LogicalDirection.Forward);
StringComparison stringComparison = StringComparison.CurrentCulture;
Int32 indexInRun = textRun.IndexOf(search, stringComparison);
if (indexInRun >= 0)
{
position = position.GetPositionAtOffset(indexInRun);
if (position != null)
{
TextPointer nextPointer = position.GetPositionAtOffset(search.Length);
TextRange textRange = new TextRange(position, nextPointer);
textRange.ApplyPropertyValue(TextElement.BackgroundProperty,
new SolidColorBrush(Colors.Yellow));
}
}
}
for(text指针位置=newDocument.ContentStart;
position!=null&&position.CompareTo(newDocument.ContentEnd)=0)
{
位置=位置。GetPositionAtOffset(indexInRun);
如果(位置!=null)
{
text指针nextPointer=position.GetPositionAtOffset(search.Length);
TextRange TextRange=新的TextRange(位置,下一个指针);
textRange.ApplyPropertyValue(TextElement.BackgroundProperty,
新的SolidColorBrush(Colors.Yellow));
}
}
}
kzub
的答案似乎对我不起作用,因此我还创建了一个解决方案,扩展了user007
,以突出显示文本指针文本中的所有子字符串实例。它还忽略大小写,并将突出显示所有匹配项:
public static void HighlightWords(TextPointer text, string searchWord, string stringText)
{
int instancesOfSearchKey = Regex.Matches(stringText.ToLower(), searchWord.ToLower()).Count;
for (int i = 0; i < instancesOfSearchKey; i++)
{
int lastInstanceIndex = HighlightNextInstance(text, searchWord);
if (lastInstanceIndex == -1)
{
break;
}
text = text.GetPositionAtOffset(lastInstanceIndex);
}
}
private static int HighlightNextInstance(TextPointer text, string searchWord)
{
int indexOfLastInstance = -1;
while (true)
{
TextPointer next = text.GetNextContextPosition(LogicalDirection.Forward);
if (next == null)
{
break;
}
TextRange newText = new TextRange(text, next);
int index = newText.Text.ToLower().IndexOf(searchWord.ToLower());
if (index != -1)
{
indexOfLastInstance = index;
}
if (index > 0)
{
TextPointer start = text.GetPositionAtOffset(index);
TextPointer end = text.GetPositionAtOffset(index + searchWord.Length);
TextRange textRange = new TextRange(start, end);
textRange.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Colors.Yellow));
}
text = next;
}
return indexOfLastInstance;
}
publicstaticvoidhighlightwords(text指针文本、stringsearchword、stringstringtext)
{
int instancesOfSearchKey=Regex.Matches(stringText.ToLower(),searchWord.ToLower()).Count;
for(int i=0;i0)
{
TextPointer start=text.GetPositionAtOffset(索引);
TextPointer end=text.GetPositionAtOffset(index+searchWord.Length);
TextRange TextRange=新的TextRange(开始、结束);
textRange.ApplyPropertyValue(TextElement.BackgroundProperty,新的SolidColorBrush(Colors.Yellow));
}
text=下一个;
}
回归指数;
}
非常感谢您的帮助。我正在尝试您的代码,但它只突出显示搜索文本的第一次出现。我现在正试图修改它以显示所有发生的事件。