I want to make part of the text of a textblock bold. This is what i tried in the IValueConverter but it does not seem to work.
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();
}
}
This does not make the Answer bold.
This is how i am using it in XAML.
<TextBlock Height="Auto" Width="Auto" MaxHeight="64" Text="{Binding Path=QuestionAnswer, Mode=OneWay, Converter={x:Static Highlighter}}" />
Is there a way i can achieve this by formatting the text or by sending the TextBlock to the converter?
It is definitely possible to do with TextBlock
control, but considering all the efforts you might want to switch to other control (ItemsControl
for example).
Anyway, here is a solution. There are actually several problems to solve:
TextBlock.Text
property is string
, and you can't assign preformatted text to itTextBlock.Inlines
can accept formatted text, but it is read-only propertyInline
objects, but I don't know any)You can create an attached property to deal with the first 2 problems:
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 would change just a bit:
<TextBlock local:TextBlockEx.FormattedText="{Binding Path=QuestionAnswer,
Mode=OneWay,
Converter={x:Static Highlighter}}" />
Note that you'll need to map you namespace where TextBlockEx
is declared in xmlns:local="clr-namepace:<namespace_name>"
in XAML.
Now you need to construct formatted text in converter instead of plain text to solve the last 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;
}
Ya, something like this should put ya on track;
<TextBlock>
<Run Text="Question / Binding / Whatever..."/>
<Run Text="Answer / Binding / Whatever..." FontWeight="Bold"/>
</TextBlock>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With