2012-12-27 13 views
5

Ich möchte einen Teil des Textes eines Textblock fett machen. Das habe ich im IValueConverter versucht, aber es scheint nicht zu funktionieren.Formatieren Sie einen Teil des Textes von TextBlock mit iValueConverter

public class Highlighter : IValueConverter 
    { 


     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      if (value == null) 
      { 
       return null; 
      } 

      return "Question1:<Bold>Answer1</Bold>, Question2:<Bold>Answer2</Bold>, Question3:<Bold>Answer3</Bold>"; 

     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

Dies macht die Antwort nicht fett.

Dies ist, wie ich es in XAML verwende.

Gibt es eine Möglichkeit, dies zu erreichen, indem Sie den Text formatieren oder den TextBlock an den Konverter senden?

+0

TextBlock- nicht Rich-Text nicht unterstützt, so wenn Sie Stile auf Ihren Text anwenden möchten oder Sie haben Zerlegen Sie Ihren Text in Läufen (wie von Chris demonstriert) oder verwenden Sie ein Steuerelement, das Rich Text unterstützt. – Ucodia

Antwort

12

Es ist durchaus möglich, mit TextBlock Kontrolle zu tun, aber alle Anstrengungen Erwägen Sie mit anderen Steuer (ItemsControl zum Beispiel) wechseln möchten.

Wie auch immer, hier ist eine Lösung. Es gibt tatsächlich einige Probleme zu lösen:

  1. TextBlock.Text Eigenschaft ist string, und Sie können vorformatierte Text, um ihn nicht zuordnen
  2. TextBlock.Inlines formatierten Text annehmen können, aber es ist schreibgeschützt Eigenschaft
  3. Sie‘ ll formatiert sich (wahrscheinlich es mit Tags sind einfache Möglichkeiten, um zu analysieren Text und produzieren als eine Sammlung von Inline Objekte formatierte Ausgabe, aber ich weiß nicht) Text müssen

Sie können einen angeschlossenen propert erstellen y mit den ersten zwei Probleme zu bewältigen:

public static class TextBlockEx 
{ 
    public static Inline GetFormattedText(DependencyObject obj) 
    { 
     return (Inline)obj.GetValue(FormattedTextProperty); 
    } 

    public static void SetFormattedText(DependencyObject obj, Inline value) 
    { 
     obj.SetValue(FormattedTextProperty, value); 
    } 

    public static readonly DependencyProperty FormattedTextProperty = 
     DependencyProperty.RegisterAttached(
      "FormattedText", 
      typeof(Inline), 
      typeof(TextBlockEx), 
      new PropertyMetadata(null, OnFormattedTextChanged)); 

    private static void OnFormattedTextChanged(
     DependencyObject o, 
     DependencyPropertyChangedEventArgs e) 
    { 
     var textBlock = o as TextBlock; 
     if(textBlock == null) return; 

     var inline = (Inline)e.NewValue; 
     textBlock.Inlines.Clear(); 
     if(inline != null) 
     { 
      textBlock.Inlines.Add(inline); 
     } 
    } 
} 

XAML nur ein wenig ändern würde:

<TextBlock local:TextBlockEx.FormattedText="{Binding Path=QuestionAnswer, 
                Mode=OneWay, 
                Converter={x:Static Highlighter}}" /> 

Beachten Sie, dass Sie benötigen, um Sie Namespace kartieren, wo TextBlockEx in xmlns:local="clr-namepace:<namespace_name>" in XAML deklariert wird.

Jetzt müssen Sie formatierten Text in Text anstelle von einfachen Konverter konstruieren, um das letzte Problem zu lösen:

public object Convert(object value, Type targetType, object parameter, 
    CultureInfo culture) 
{ 
    if(value == null) 
    { 
     return null; 
    } 

    var span = new Span(); 
    span.Inlines.Add(new Run("Question1: ")); 
    span.Inlines.Add(new Run("Answer1") { FontWeight = FontWeights.Bold }); 
    span.Inlines.Add(new Run(", ")); 

    span.Inlines.Add(new Run("Question2: ")); 
    span.Inlines.Add(new Run("Answer2") { FontWeight = FontWeights.Bold }); 
    span.Inlines.Add(new Run(", ")); 

    span.Inlines.Add(new Run("Question3: ")); 
    span.Inlines.Add(new Run("Answer3") { FontWeight = FontWeights.Bold }); 

    return span; 
} 
2

Ya, so etwas sollte dich auf die Spur bringen;

<TextBlock> 
    <Run Text="Question/Binding/Whatever..."/> 
    <Run Text="Answer/Binding/Whatever..." FontWeight="Bold"/> 
</TextBlock> 
+0

Ich kann das nicht verwenden, da es eine Anzahl von Fragen geben könnte. – Asdfg

+0

Warum nicht? Machen Sie es zu einem ContentControl, schlagen Sie es in ein ItemsControl oder ListBox oder etwas, und voila! –