1

I have a list of strings in my ViewModel with the following format:

 This is an <b>example.<b>

I want to have some kind of text control in my view that will display the formatted text via DataBinding*, like this:

This is an example.

I don't find any built-in control that can behave like this.

Does anyone know how to deal with it?

gotqn
  • 42,737
  • 46
  • 157
  • 243
Rom Shiri
  • 1,390
  • 4
  • 16
  • 29

2 Answers2

5

You can use Run:

<TextBlock FontSize="30">
    <Run>This is an</Run>
    <Run FontWeight="Bold" Text=" example"/>
</TextBlock>

For this you will have to parse your strings, select bold sections, and define content in the code behind. A very simple example can look like this:

string example = @"This is an <b>example.</b>";
var str = example.Split(new string[] { "<b>", "</b>" }, StringSplitOptions.None);
for (int i = 0; i < str.Length; i++)
    myTextBlock.Inlines.Add(new Run { Text = str[i], FontWeight = i % 2 == 1 ? FontWeights.Bold : FontWeights.Normal });

Edit - using with Binding

If you want to use the above procedure with Binding, then it's not so simple - TextBlock.Inlines is not a DependencyProperty, so we cannot use it. Nevertheless there is a way to do it - you need to extend somehow your TextBlock - here is another pitfall - it's sealed class so no inheritance. In this case we will have to use another class (here is also a good example):

public static class TextBlockExtension
{
    public static string GetFormattedText(DependencyObject obj)
    { return (string)obj.GetValue(FormattedTextProperty); }

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

    public static readonly DependencyProperty FormattedTextProperty =
        DependencyProperty.Register("FormattedText", typeof(string), typeof(TextBlockExtension),
        new PropertyMetadata(string.Empty, (sender, e) =>
        {
            string text = e.NewValue as string;
            var textBl = sender as TextBlock;
            if (textBl != null)
            {
                textBl.Inlines.Clear();
                var str = text.Split(new string[] { "<b>", "</b>" }, StringSplitOptions.None);
                for (int i = 0; i < str.Length; i++)
                    textBl.Inlines.Add(new Run { Text = str[i], FontWeight = i % 2 == 1 ? FontWeights.Bold : FontWeights.Normal });
            }
        }));
}

Then you can use it in xaml like this:

<TextBlock local:TextBlockExtension.FormattedText="{Binding MyText}"/>
Community
  • 1
  • 1
Romasz
  • 29,662
  • 13
  • 79
  • 154
  • 1
    I wouldn't remove empty entries. That would break "this should not all be bold>" – ZombieSheep Dec 15 '14 at 15:07
  • @ZombieSheep You are right. Nevertheless it's still a very basic exampel and needs more improvemets (it also depend on OP's implementation). This should help the OP, the rest I'll leave to him. – Romasz Dec 15 '14 at 15:15
0

You could use the RichTextBlock control. Something like:

<RichTextBlock>
 <Paragraph>
    This is an <Bold>example</Bold>
 </Paragraph>
</RichTextBlock>
cjgaliana
  • 168
  • 2
  • 10