Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 突出显示FlowDocument中的部分文本_C#_Wpf_Highlight_Flowdocument - Fatal编程技术网

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=下一个;
}
回归指数;
}

非常感谢您的帮助。我正在尝试您的代码,但它只突出显示搜索文本的第一次出现。我现在正试图修改它以显示所有发生的事件。