如何使用突出显示的查询词在 WPF 项目控件中显示搜索结果 [英] How to display search results in a WPF items control with highlighted query terms

查看:38
本文介绍了如何使用突出显示的查询词在 WPF 项目控件中显示搜索结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 WPF ItemsControl 中显示搜索结果,并突出显示查询词.

I'd like to display search results within a WPF ItemsControl with the query terms highlighted.

我使用的搜索引擎 Lucene.Net 带有荧光笔插件,返回带有查询词标记如下:

The search engine I use, Lucene.Net with the Highlighter plugin, returns strings with the query terms marked up like so:

...these <Bold>results</Bold> were found to be statistically significant...

我可以指示 Highlighter 插件使用任何一组标记来包装查询词.我不限于上面示例中的 标记.对于 WPF,我可能会让这些 <Run/> 元素附加一个样式.

I can instruct the Highlighter plugin to use any set of markup tags to wrap a query term. I'm not limited to the <Bold> tag in the example above. For WPF, I'd likely make these <Run/> elements with a style attached.

挑战在于获取给定的字符串并将其呈现为我用于搜索结果的数据模板中的实际 XAML".换句话说,我想看到这样的东西:

The challenge is to take the string I've been given and render it as if it were "actual XAML" within the datatemplate I'm using for search results. In other words, I want to see something like this:

...这些结果被发现具有统计学意义...

...these results were were found to be statistically significant...

但我正在努力解决如何将数据绑定与数据模板中 XAML 字符串的动态呈现相结合.这里最好的方法是什么?

But I'm struggling with how to combine databinding with dynamic rendering of an XAML string within the datatemplate. What's the best approach here?

  1. 使用 UserControl 显示每个搜索结果并从代码隐藏调用 XamlReader.Load()?
  2. 构造一个包含搜索结果字符串的 FlowDocument 并使用 FlowDocumentScrollViewer 显示结果?
  3. 完全不同的东西......?

推荐答案

我接受了 dthrasers answer 并提出了需要用于 XML 解析器.他很好地解释了 他的博客,但是这不需要我添加任何额外的库,我是这样做的.

I took dthrasers answer and took out the need for an XML parser. He does a great job explaining each of the pieces in his blog, However this didn't require me to add any extra libraries, here's how I did it.

第一步,制作一个转换器类:

Step one, make a converter class:

class StringToXamlConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string input = value as string;
        if (input != null)
        {
            var textBlock = new TextBlock();
            textBlock.TextWrapping = TextWrapping.Wrap;
            string escapedXml = SecurityElement.Escape(input);
            
            while (escapedXml.IndexOf("|~S~|") != -1) {
                //up to |~S~| is normal
                textBlock.Inlines.Add(new Run(escapedXml.Substring(0, escapedXml.IndexOf("|~S~|"))));
                //between |~S~| and |~E~| is highlighted
                textBlock.Inlines.Add(new Run(escapedXml.Substring(escapedXml.IndexOf("|~S~|") + 5,
                                          escapedXml.IndexOf("|~E~|") - (escapedXml.IndexOf("|~S~|") + 5))) 
                                          { FontWeight = FontWeights.Bold, Background= Brushes.Yellow });
                //the rest of the string (after the |~E~|)
                escapedXml = escapedXml.Substring(escapedXml.IndexOf("|~E~|") + 5);
            }

            if (escapedXml.Length > 0)
            {
                textBlock.Inlines.Add(new Run(escapedXml));                      
            }
            return textBlock;
        }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException("This converter cannot be used in two-way binding.");
    }
}

第二步:使用 ContentBlock 代替 TextBlock.将字符串(您将用于 textBlock)传递给内容块,如下所示:

Step two: Instead of a TextBlock use a ContentBlock. Pass in the string (you would of used for your textBlock) to the content block, like so:

<ContentControl
               Margin="7,0,0,0"
               HorizontalAlignment="Left"
               VerticalAlignment="Center"
               Content="{Binding Description, Converter={StaticResource CONVERTERS_StringToXaml}, Mode=OneTime}">
</ContentControl>

第三步:确保您传入的测试使用 |~S~||~E~| 进行标记.让突出显示开始!

Step three: Make sure the test you pass in is tokenized with |~S~| and |~E~|. And let the highlighting begin!

注意事项:
您可以在运行中更改样式以确定突出显示文本的内容和方式
确保将 Converter 类添加到命名空间和资源中.这可能还需要重建才能工作.

Notes:
You can change the style in the run to determine what and how your text is highlighted
Make sure you add your Converter class to your namespace and resources. This might also require a rebuild to get working.

这篇关于如何使用突出显示的查询词在 WPF 项目控件中显示搜索结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆