2015-06-05 42 views
1

目標是使用匹配的輸入關鍵字在文本塊中粗體顯示文本的單詞。如何使用附加屬性在文本塊中用粗體突出顯示指定關鍵字的單詞

例如:Stackoverflow是一個非常有用的,繼續使用Stackoverflow來提高你的技能。

此外,在關鍵詞是:計算器,現在應該顯示爲

#1是一個非常有用的,繼續使用#1來提升自己的技能。

我試圖使用附加屬性來實現相同的目標。下面是相同

public class HighLightKeyWord : DependencyObject 
{ 

    //This word is used to specify the word to highlight 
    public static readonly DependencyProperty BoldWordProperty = DependencyProperty.RegisterAttached("BoldWord", typeof(string), typeof(HighLightKeyWord), 
     new PropertyMetadata(string.Empty, OnBindingTextChanged)); 

    public static string GetBoldWord(DependencyObject obj) 
    { 
     return (string)obj.GetValue(BoldWordProperty); 
    } 

    public static void SetBoldWord(DependencyObject obj, string value) 
    { 
     obj.SetValue(BoldWordProperty, value); 
    } 

    private static void OnBindingTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 

     var _Key = e.NewValue as string; 
     var textblk = d as TextBlock; 
     string SourceText = textblk.Text; 
     SetBold(_Key, textblk, SourceText); 

    } 

    private static void SetBold(string key, TextBlock text, string SourceText) 
    { 
     text.Inlines.Clear(); 
     var words = SourceText.Split(' '); 
     for (int i = 0; i < words.Length; i++) 
     { 
      var word = words[i]; 
      var inline = new Run() { Text = word + ' ' }; 
      if (String.Compare(word, key, StringComparison.CurrentCultureIgnoreCase) == 0) 
      { 
       inline.FontWeight = FontWeights.Bold; 
      } 
      text.Inlines.Add(inline); 
     } 
    } 

} 

//綁定對象的主要

 StackOverFlow stkovrflw = new StackOverFlow(); 
     stkovrflw.Text = "Stackoverflow is a very helpful,keep using Stackoverflow to sharpen your skills."; 
     stkovrflw.KeyWord = "Stackoverflow"; 
     this.DataContext = stkovrflw; 

卡代碼在XAML我綁定的值作爲

<TextBlock Text="{Binding Path=Text}" loc:HighLightKeyWord.BoldWord="{Binding Path=KeyWord}" /> 

上面的代碼工作正常,但是當我通過數據綁定直接設置了xaml中的HighlightText屬性,Text塊中的Text屬性在OnBindingTextChanged方法中變爲空,並且只有在依賴項prop erty被設置。 我使用了基於拼寫檢查概念的這種設計,以便其他茶友可以在他們的項目中重複使用我附加的屬性。 任何人都可以建議如何解決這個問題?

回答

1

無論您想修改TextBlock FontWeight屬性還是其他顯示屬性,我都已經編寫了下面的靜態方法,並發現它非常有用。 (注:該方法示出了通過修改Foreground屬性高亮文本相同的原理可以用於任何其他的TextBlock顯示屬性。)

static Brush DefaultHighlight = new SolidColorBrush(Colors.Red); 

    public static void SetTextAndHighlightSubstring(this TextBlock targetTextBlock, string sourceText, string subString, Brush highlight = null) 
    { 
     if (targetTextBlock == null || String.IsNullOrEmpty(sourceText) || String.IsNullOrEmpty(subString)) 
      return; 
     targetTextBlock.Text = ""; 
     var subStringPosition = sourceText.ToUpper().IndexOf(subString); 
     if (subStringPosition == -1) 
     { 
      targetTextBlock.Inlines.Add(new Run { Text = sourceText }); 
      return; 
     } 
     var subStringLength = subString.Length; 
     var header = sourceText.Substring(0, subStringPosition); 
     subString = sourceText.Substring(subStringPosition, subStringLength); 
     var trailerLength = sourceText.Length - (subStringPosition + subStringLength); 
     var trailer = sourceText.Substring(subStringPosition + subStringLength, trailerLength); 
     targetTextBlock.Inlines.Add(new Run { Text = header }); 
     targetTextBlock.Inlines.Add(new Run { Text = subString, Foreground = highlight ?? DefaultHighlight }); 
     targetTextBlock.Inlines.Add(new Run { Text = trailer }); 
    } 

可以使用的TextBlock擴展語法像這樣調用此方法:

TextBlockTitle.SetTextAndHighlightSubstring(_categoryItem.ItemText, _searchText); 

在這個例子中,下面的顯示結果:

enter image description here

0

我最近在跑與破損的文本綁定相同的問題。我意識到這是一個古老的問題,但我想我會分享我的發現無論如何。

基本上,Text屬性的數據綁定在Inline.Clear被調用的時候被切斷。我解決這個問題的方法是添加一個內部文本依賴項屬性,該屬性複製了文本的綁定,因此後續文本更改將繼續觸發高亮顯示。

在清除text.Inlines之前,嘗試添加類似的內容。

protected static string GetInternalText(DependencyObject obj) 
{ 
    return (string)obj.GetValue(InternalTextProperty) 
} 

protected static void SetInternalText(DependencyObject obj, string value) 
{ 
    obj.SetValue(InternalTextProperty, value); 
} 

// Using a DependencyProperty as the backing store for InternalText. This enables animation, styling, binding, etc... 
protected static readonly DependencyProperty InternalTextProperty = 
     DependencyProperty.RegisterAttached("InternalText", typeof(string), 
typeof(HighlightableTextBlock), new PropertyMetadata(string.Empty, OnInternalTextChanged)); 

private static void SetBold(string key, TextBlock text, string SourceText) 
{ 
    //Add the following code to replicate text binding 
    if (textblock.GetBindingExpression(HighlightableTextBlock.InternalTextProperty) == null) 
    { 
     var textBinding = text.GetBindingExpression(TextBlock.TextProperty); 

     if (textBinding != null) 
     { 
      text.SetBinding(HighLightKeyWord.InternalTextProperty, textBinding.ParentBindingBase); 
     } 
    } 

    ... 
} 

在InternalTextProperty的propertyChangeCallback你可以有相同的代碼OnBindingTextChanged(),或者你可以將它們重構爲另一種方法。

對於那些不想編寫自己的代碼。我創建了一個輕量級的nuget包,爲常規的TextBlock添加了突出顯示。您可以保持大部分代碼完整,只需添加一些附加屬性。默認情況下,加載項支持突出顯示,但您也可以在關鍵字上啓用粗體,斜體和下劃線。

https://www.nuget.org/packages/HighlightableTextBlock/

源是在這裏:https://github.com/kthsu/HighlightableTextBlock

相關問題