如何使用突出显示的查询术语在WPF项目控件中显示搜索结果

dth*_*her 8 wpf xaml datatemplate itemscontrol

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

我使用的搜索引擎,带有Highlighter插件的Lucene.Net,返回带有标记的查询字符串,如下所示:

...these <Bold>results</Bold> were found to be statistically significant...
Run Code Online (Sandbox Code Playgroud)

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

挑战是获取我已经给出的字符串并将其呈现为我在搜索结果中使用的数据模板中的"实际XAML".换句话说,我想看到这样的事情:

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

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

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

Syn*_*les 12

我接受了dthrasers的回答,并且需要一个XML解析器.他很好地解释了他博客中的每一个部分,但是这并没有要求我添加任何额外的库,这就是我如何做到的.

第一步,制作转换器类:

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.");
    }
}
Run Code Online (Sandbox Code Playgroud)

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

<ContentControl
               Margin="7,0,0,0"
               HorizontalAlignment="Left"
               VerticalAlignment="Center"
               Content="{Binding Description, Converter={StaticResource CONVERTERS_StringToXaml}, Mode=OneTime}">
</ContentControl>
Run Code Online (Sandbox Code Playgroud)

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

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


dth*_*her 9

我找到了一种使用自定义IValueConverter将突出显示应用于搜索结果的方法.转换器获取文本片段,将其格式化为有效的XAML标记,并使用XamlReader将标记实例化为框架对象.

完整的解释相当长,所以我把它发布到我的博客:突出显示WPF TextBlock中的查询条款

  • 收到500 Http错误,您(或其他人)可以修复链接吗? (3认同)

Mar*_*art 2

A的集合中TextBlock可以包含多个Runs Inlines。您可以在代码或 XAML 中构建它:

<TextBlock>
    <Run>... these </Run>
    <Run FontWeight="Bold">results</Run>
    <Run> were found...</Run>
</TextBlock>
Run Code Online (Sandbox Code Playgroud)