2012-12-27 11 views
5

Chcę, aby część tekstu bloku tekstu była pogrubiona. To jest to, co próbowałem w IValueConverter, ale to nie działa.Formatowanie części tekstu obiektu TextBlock za pomocą 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(); 
     } 
    } 

Nie powoduje to pogrubienia odpowiedzi.

W ten sposób używam go w XAML.

<TextBlock Height="Auto" Width="Auto" MaxHeight="64" Text="{Binding Path=QuestionAnswer, Mode=OneWay, Converter={x:Static Highlighter}}" /> 

Czy istnieje sposób mogę to osiągnąć przez sformatowanie tekstu lub wysyłając TextBlock do konwertera?

+0

TextBlock nie obsługuje tekst sformatowany, więc jeśli chcesz zastosować style do tekstu lub trzeba będzie podziel tekst na biegi (jak pokazał Chris) lub użyj formantu obsługującego tekst sformatowany. – Ucodia

Odpowiedz

12

Jest to z pewnością możliwe do zrobienia z TextBlock kontrolą, ale biorąc pod uwagę wszystkie wysiłki może chcesz przejść do innych kontroli (ItemsControl na przykład).

W każdym razie, oto rozwiązanie. Jest kilka problemów do rozwiązania:

  1. TextBlock.Text nieruchomość jest string, i nie można przypisać do niego tekst preformatowany
  2. TextBlock.Inlines może zaakceptować tekst sformatowany, ale jest to właściwość tylko do odczytu
  3. You” będziesz musiał sam format tekstowy (prawdopodobnie istnieją proste sposoby, aby zanalizować tekst z tagami i produkują sformatowany wyjście jako zbiór Inline obiektów, ale ja nie wiem)

można utworzyć załączony propert y do czynienia z pierwszych 2 problemy:

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 zmieniłaby tylko trochę:

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

Pamiętaj, że musisz mapie nazw gdzie TextBlockEx jest zadeklarowana w xmlns:local="clr-namepace:<namespace_name>" w XAML.

Teraz trzeba skonstruować sformatowany tekst w konwerterze zamiast zwykłego tekstu, aby rozwiązać ten ostatni problem:

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, coś w tym stylu powinno postawić cię na dobrej drodze;

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

Nie mogę tego użyć, ponieważ może być n liczba pytań. – Asdfg

+0

Dlaczego nie? Zrób to ContentControl, uderz go w ItemsControl lub ListBox lub coś takiego, i voila! –

Powiązane problemy