none
How can I bind a textblock to formatted text?

    Question

  • I have a textblock that has to display formatted text. I wrote a converter to convert the input string to inlines, but because inlines isn't a dependency property, I can't use the converter in a binding :( Binding to Text doesn't work, so my question is: How can I show a formatted text using bindings? Thanks in advance.
    Tuesday, October 20, 2009 1:49 PM

Answers

  • You can make your own textblock control that accept InlineCollection as DP

    public class CustomTextBlock : TextBlock
        {
            public InlineCollection InlineCollection
            {
                get
                {
                    return (InlineCollection)GetValue(InlineCollectionProperty);
                }
                set
                {
                    SetValue(InlineCollectionProperty, value);
                }
            }

            public static readonly DependencyProperty InlineCollectionProperty = DependencyProperty.Register(
                "InlineCollection",
                typeof(InlineCollection),
                typeof(CustomTextBlock),
                    new UIPropertyMetadata((PropertyChangedCallback)((sender, args) =>
                    {
                        CustomTextBlock textBlock = sender as CustomTextBlock;

                        if (textBlock != null)
                        {
                            textBlock.Inlines.Clear();

                            InlineCollection inlines = args.NewValue as InlineCollection;

                            if (inlines != null)
                                textBlock.Inlines.AddRange(inlines.ToList());
                        }
                    })));
        }


    Use your converter that return Inlines like that:


     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                if (!string.IsNullOrEmpty(value as string))
                {
                    FlowDocument fd = new FlowDocument();

                    string[] text = ((string)value).Split(' ');

                    Paragraph p = new Paragraph();
                    StringBuilder sb = new StringBuilder();
                  
    //add text and pictures, etc. and return now InlineCollection instead of FlowDocument
                   
                    return p.Inlines;
                }
                else
                {
                    return new FlowDocument();
                }
            }



    And use it in xaml like that :

    <Window x:Class="WpfApplication4.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication4"
        Title="Window1" Height="300" Width="300">
        
        <Window.Resources>
            <local:YourConverter x:Key="YourConverter" />
        </Window.Resources>
        
        <Grid>
            <local:CustomTextBlock HorizontalAlignment="Center"
                                 VerticalAlignment="Center"
                                 Background="YellowGreen"
                                 OverridesDefaultStyle="False"
                                 TextWrapping="Wrap"
                                 InlineCollection="{Binding Converter={StaticResource YourConverter}}" />
        </Grid>
    </Window>


    • Marked as answer by _patrick_ Wednesday, October 21, 2009 1:26 PM
    Wednesday, October 21, 2009 10:58 AM

All replies

  • Hi _patrick_,

    I am not sure why you can not use Converters unless I can see what you've done. So now I can only suggest you use StringFormat property of the Binding.

    Please check out this article. Let me know if it helps.

    Best regards,
    Bruce Zhou


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Wednesday, October 21, 2009 8:43 AM
  • Textblock is there just to show some text. If you want some additional formatting, take a look at the Label class, which supports content instead of a text property alone.

    You might want to take a look at this thread.
    Geert van Horrik - CatenaLogic
    Visit my blog: http://blog.catenalogic.com

    Looking for a way to deploy your updates to all your clients? Try Updater!
    Wednesday, October 21, 2009 9:26 AM
  • You can make your own textblock control that accept InlineCollection as DP

    public class CustomTextBlock : TextBlock
        {
            public InlineCollection InlineCollection
            {
                get
                {
                    return (InlineCollection)GetValue(InlineCollectionProperty);
                }
                set
                {
                    SetValue(InlineCollectionProperty, value);
                }
            }

            public static readonly DependencyProperty InlineCollectionProperty = DependencyProperty.Register(
                "InlineCollection",
                typeof(InlineCollection),
                typeof(CustomTextBlock),
                    new UIPropertyMetadata((PropertyChangedCallback)((sender, args) =>
                    {
                        CustomTextBlock textBlock = sender as CustomTextBlock;

                        if (textBlock != null)
                        {
                            textBlock.Inlines.Clear();

                            InlineCollection inlines = args.NewValue as InlineCollection;

                            if (inlines != null)
                                textBlock.Inlines.AddRange(inlines.ToList());
                        }
                    })));
        }


    Use your converter that return Inlines like that:


     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                if (!string.IsNullOrEmpty(value as string))
                {
                    FlowDocument fd = new FlowDocument();

                    string[] text = ((string)value).Split(' ');

                    Paragraph p = new Paragraph();
                    StringBuilder sb = new StringBuilder();
                  
    //add text and pictures, etc. and return now InlineCollection instead of FlowDocument
                   
                    return p.Inlines;
                }
                else
                {
                    return new FlowDocument();
                }
            }



    And use it in xaml like that :

    <Window x:Class="WpfApplication4.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication4"
        Title="Window1" Height="300" Width="300">
        
        <Window.Resources>
            <local:YourConverter x:Key="YourConverter" />
        </Window.Resources>
        
        <Grid>
            <local:CustomTextBlock HorizontalAlignment="Center"
                                 VerticalAlignment="Center"
                                 Background="YellowGreen"
                                 OverridesDefaultStyle="False"
                                 TextWrapping="Wrap"
                                 InlineCollection="{Binding Converter={StaticResource YourConverter}}" />
        </Grid>
    </Window>


    • Marked as answer by _patrick_ Wednesday, October 21, 2009 1:26 PM
    Wednesday, October 21, 2009 10:58 AM
  • I guess I didn't explain myself well. I just wanted a textblock with flow content elements at run-time. I've ended up with a solution similar to Fanou360's - which is the same I thought of before, but I don't really like the approach of creating a new control just to change Inlines into a dependency property.
    Wednesday, October 21, 2009 1:25 PM