Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XAML Convert textblock text to Inlines

I want to set this kind of text on TextBlock in a UWP project :

"<Bold>" + variable + "</Bold>"

But set it to Text value do not consider <Bold> tags.

So i searched how to do and the only one answer is "creat Inlines and add it to your textBlock". but i don't want to do it on my View Model.

So i'm looking for a converter to replace my text attribute by a inlines collection to set on my textBlock. I found some example (https://social.msdn.microsoft.com/Forums/en-US/1a1af975-e186-4167-b1c9-cc86afcdd93a/how-to-show-text-in-textblock-as-rich-text-format?forum=wpf), but not working on universal Windows apps (UWP).

I tried this but i have an error (unable to cast Binding to string):

<TextBlock  x:Name="newsArticleSections"
                            Tag="{Binding RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource TextToRunConverter}, ConverterParameter={Binding ArticleSections}}"/>

And this is my converter :

public object Convert(object value, Type targetType, object parameter, string language)
    {
        TextBlock textblock = value as TextBlock;

        textblock.ClearValue(TextBlock.TextProperty);
        Run run = new Run();
        run.Text = (string)parameter;
        textblock.Inlines.Add(run);
        return null;
    }

It's just the ways that i had explored, but with no result for the moment. Does someone has another idea ?

like image 724
Geoffrey Lalloué Avatar asked Dec 04 '15 18:12

Geoffrey Lalloué


People also ask

Is TextBlock editable?

TextBlocks can be edited by users using the TextEditingTool. The HTMLInfo that a given TextBlock uses as its text editor can be customized by setting the textEditor property.

What is TextBlock?

Text block is the primary control for displaying read-only text in apps. You can use it to display single-line or multi-line text, inline hyperlinks, and text with formatting like bold, italic, or underlined.

How do I add a paragraph in TextBlock WPF?

Add(new Run("Text of paragraph.")); // Create a span with the content of the paragraph (FontSize 25 and FontWeight Bold stay alive) Span span = new Span(para. ContentStart, para. ContentEnd); // Create a TextBlock with the span (FontSize 25 and FontWeight Bold get lost) TextBlock textBlock = new TextBlock(); textBlock.


2 Answers

@devuxer answer was a good idea, but only for WPF project. So i used it to make UWP solution and it works :

Create a Formatter class :

public class TextBlockFormatter
{
    public static readonly DependencyProperty FormattedTextProperty = DependencyProperty.RegisterAttached(
    "FormattedText",
    typeof(string),
    typeof(TextBlockFormatter),
    new PropertyMetadata(null, FormattedTextPropertyChanged));

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

    public static string GetFormattedText(DependencyObject textBlock)
    {
        return (string)textBlock.GetValue(FormattedTextProperty);
    }

    private static void FormattedTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Clear current textBlock
        TextBlock textBlock = d as TextBlock;
        textBlock.ClearValue(TextBlock.TextProperty);
        textBlock.Inlines.Clear();
        // Create new formatted text
        string formattedText = (string)e.NewValue ?? string.Empty;
        string @namespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
        formattedText = $@"<Span xml:space=""preserve"" xmlns=""{@namespace}"">{formattedText}</Span>";
        // Inject to inlines
        var result = (Span)XamlReader.Load(formattedText);
        textBlock.Inlines.Add(result);
    }

}

And add this reference to your XAML file :

xmlns:helpers="using:MyProject.Helpers"

To use the formatter, simply add a TextBlock and declare your binding on FormattedText, like this :

<TextBlock  x:Name="textBlock" helpers:TextBlockFormatter.FormattedText="{Binding Content}">
like image 171
Geoffrey Lalloué Avatar answered Oct 13 '22 12:10

Geoffrey Lalloué


I've been using the following solution for WPF projects (not UWP), so I'm not sure if it will work for you, but feel free to give it a try.

You begin by putting the following into a class file within, say, a Helpers folder inside your project:

public class Formatter
{
    public static readonly DependencyProperty FormattedTextProperty = DependencyProperty.RegisterAttached(
        "FormattedText",
        typeof(string),
        typeof(Formatter),
        new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsMeasure, FormattedTextPropertyChanged));

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

    public static string GetFormattedText(DependencyObject textBlock)
    {
        return (string)textBlock.GetValue(FormattedTextProperty);
    }

    private static void FormattedTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var textBlock = d as TextBlock;
        if (textBlock == null) return;
        const string @namespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
        var formattedText = (string)e.NewValue ?? string.Empty;
        formattedText = $@"<Span xml:space=""preserve"" xmlns=""{@namespace}"">{formattedText}</Span>";

        textBlock.Inlines.Clear();
        using (var xmlReader = XmlReader.Create(new StringReader(formattedText)))
        {
            var result = (Span)XamlReader.Load(xmlReader);
            textBlock.Inlines.Add(result);
        }
    }
}

Then, in your XAML file, reference the namespace, like so:

xmlns:helpers="clr-namespace:MyProject.Helpers"

To use the formatter, simply add a TextBlock and declare your binding on FormattedText (instead of Text), like this:

<TextBlock helpers:Formatter.FormattedText="{Binding Content}" />
like image 37
devuxer Avatar answered Oct 13 '22 11:10

devuxer