【问题标题】:How to display search results in a WPF items control with highlighted query terms如何使用突出显示的查询词在 WPF 项目控件中显示搜索结果
【发布时间】:2011-04-13 07:36:26
【问题描述】:

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

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

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

我可以指示 Highlighter 插件使用任何一组标记标签来包装查询词。我不限于上面示例中的&lt;Bold&gt; 标签。对于 WPF,我可能会制作这些带有样式的 &lt;Run/&gt; 元素。

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

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

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

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

【问题讨论】:

    标签: wpf xaml datatemplate itemscontrol


    【解决方案1】:

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

    <TextBlock>
        <Run>... these </Run>
        <Run FontWeight="Bold">results</Run>
        <Run> were found...</Run>
    </TextBlock>
    

    【讨论】:

    • 我的问题可能还不够清楚。棘手的部分是我需要在运行时将字符串更改为 XAML,而不是编译时。
    • 也许我错过了一些东西,但在我的示例中构建一个 XAML 字符串(使用一些正则表达式)并使用您的第一种方法对我来说似乎是可行的。我建议的解决方案是在运行时构建一个 TextBlock 并使用 Runs 填充其 Inlines 集合。为突出显示的 Runs 添加样式是替换 FontWeight="Bold" 的解决方案。
    • 谢谢,@Mart。你的建议让我走上了正轨。我的回答描述了我使用的方法。
    【解决方案2】:

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

    完整的解释比较长,所以我把它发布到我的博客:Highlighting Query Terms in a WPF TextBlock

    【讨论】:

    • 收到 500 Http 错误,您(或其他人)能否修复链接?
    • 哎呀。对于那个很抱歉。让我的 WordPress 网站再次排序。
    • 链接又死了。编辑链接以指向页面的缓存版本,仅供参考。
    【解决方案3】:

    我接受了dthrasers answer 并消除了对 XML 解析器的需求。他很好地解释了his blog 中的每一部分,但这并不需要我添加任何额外的库,这就是我的做法。

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

    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)传递给内容块,如下所示:

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

    第三步: 确保您通过的测试使用|~S~||~E~| 进行标记。然后开始突出显示!

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-27
      • 2017-07-14
      • 2019-03-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-23
      相关资源
      最近更新 更多