2010-09-16 66 views
5

我想在突出顯示查詢條件的WPF ItemsControl中顯示搜索結果。如何使用突出顯示的查詢條件在WPF項目控件中顯示搜索結果

我使用的搜索引擎,Lucene.Net用熒光筆插件,返回一個字符串註明像這樣的查詢詞:

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

我可以指示熒光筆插件使用任何一組標記標籤的包裝一個查詢字詞。我並不侷限於上面例子中的<Bold>標籤。對於WPF,我可能會使這些<Run/>元素具有附加的樣式。

我們面臨的挑戰是採用我給出的字符串,並將其呈現爲我用於搜索結果的數據模板中的「實際XAML」。換句話說,我希望看到這樣的事情:

...這些結果被發現在統計學上顯著...

但我與如何結合掙扎在數據模板中動態呈現XAML字符串進行數據綁定。這裏最好的方法是什麼?

  1. 使用UserControl顯示每個搜索結果並從代碼隱藏中調用XamlReader.Load()
  2. 構建一個包含搜索結果字符串的FlowDocument並使用FlowDocumentScrollViewer顯示結果?
  3. 其他完全......?

回答

0

A TextBlock可以在其Inlines集合中包含多個Run s。您可以在代碼或XAML構建它:

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

我的問題可能不夠清楚。棘手的部分是我需要在運行時將字符串更改爲XAML,而不是編譯時。 – dthrasher 2010-09-16 20:40:34

+0

也許我錯過了一些東西,但看起來對我來說是可行的,像我的示例(使用一些正則表達式)來構建XAML字符串並使用第一種方法。我建議的解決方案是在運行時構建一個TextBlock,並使用Runs填充它的Inlines集合。向突出顯示的Runs添加樣式是替代FontWeight =「Bold」的解決方案。 – Mart 2010-09-17 08:19:03

+0

謝謝,@Mart。你的建議讓我走上正軌。我的回答描述了我使用的方法。 – dthrasher 2011-03-03 16:23:37

9

我找到了一種方法來應用突出顯示搜索使用自定義的IValueConverter結果。轉換器接受一個文本片段,將其格式化爲有效的XAML標記,並使用XamlReader將標記實例化爲框架對象。

完整的解釋是相當長的,所以我已經將它貼到我的博客:Highlighting Query Terms in a WPF TextBlock

+0

我有風格去爲其他屬性,但不是背景工作 – Paparazzi 2014-01-16 22:21:28

+1

獲得500 Http錯誤,您(或其他人)可以修復鏈接? – 2014-10-28 10:42:15

+0

哎呦。對於那個很抱歉。讓我的WordPress網站再次排序。 – dthrasher 2015-02-17 16:54:55

7

我把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."); 
     } 

    } 

第二步: 相反TextBlock的使用內文。通過在字符串中(你的使用你的文本塊)的內容塊,像這樣:

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

第三步: 確保你通過測試標記化與|~S~||~E~|。讓突出顯示開始吧!

注:
你可以改變風格在運行,以確定什麼和如何你的文本被高亮
確保你把你的轉換器類,以您的命名空間和資源。這可能也需要重建才能正常工作。

相關問題