Reputation: 82437
Say I have a TextBlock
that looks like this:
<TextBlock TextWrapping="Wrap" >
Text in <Run Foreground="Red">red</Run> and <Run Foreground="Red">more</Run>
</TextBlock>
That works fine and the text is shown in red as you think it would. However, in my real example this text:
Text in <Run Foreground="Red">red</Run> and <Run Foreground="Red">more</Run>
Comes from a service call. (Including the tags.)
Is there a way to supply this text to the TextBlock
at runtime?
Upvotes: 1
Views: 1004
Reputation: 82437
I thought I would post the control that I made from King Kong's answer. (Just in case it is useful to someone else.)
public class FormatBindableTextBlock : TextBlock
{
private static readonly ParserContext parserContext;
static FormatBindableTextBlock()
{
parserContext = new System.Windows.Markup.ParserContext();
parserContext.XmlnsDictionary[""] = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
parserContext.XmlnsDictionary["x"] = "http://schemas.microsoft.com/winfx/2006/xaml";
}
public static readonly DependencyProperty FormattedContentProperty =
DependencyProperty.Register("FormattedContent", typeof(string), typeof(FormatBindableTextBlock), new UIPropertyMetadata(null, OnFormattedContentPropertyChanged));
public string FormattedContent
{
get { return (string)GetValue(FormattedContentProperty); }
set { SetValue(FormattedContentProperty, value); }
}
private static void OnFormattedContentPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
FormatBindableTextBlock textBlock = sender as FormatBindableTextBlock;
if (textBlock == null)
return;
string newFormattedContent = e.NewValue as string;
if (string.IsNullOrEmpty(newFormattedContent))
newFormattedContent = "";
newFormattedContent = "<TextBlock>" + newFormattedContent + "</TextBlock>";
TextBlock tbl = System.Windows.Markup.XamlReader.Parse(newFormattedContent, parserContext) as TextBlock;
textBlock.Inlines.Clear();
textBlock.Inlines.AddRange(tbl.Inlines.ToList());
}
}
Upvotes: 2
Reputation: 63347
In fact you have to convert all the input text into Inlines
collection (of type TextElementCollection
). However doing so requires parsing the input text yourself which is not easy. So why not use the existing parser supported by XamlReader
. By using this class, you can parse a XAML code to get an instance of a TextBlock
from which you can get the Inlines
collection and add that for your actual TextBlock
. Here is the code:
var text = "<TextBlock>Text in <Run Foreground=\"Red\">red</Run> and <Run Foreground=\"Red\">more</Run></TextBlock>";
var pc = new System.Windows.Markup.ParserContext();
pc.XmlnsDictionary[""] = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
pc.XmlnsDictionary["x"] = "http://schemas.microsoft.com/winfx/2006/xaml";
var tbl = System.Windows.Markup.XamlReader.Parse(text, pc) as TextBlock;
yourTextBlock.Inlines.Clear();
yourTextBlock.Inlines.AddRange(tbl.Inlines.ToList());
Your actual input text should be wrapped in the pair <TextBlock>
& </TextBlock>
before being used by the next code.
Upvotes: 2