Textbox with dynamic inlines
Posted by: Mark Shurmer
Have you, like me recently, discovered that you need to create specialised textblocks and add them to an existing TextBlock?
One example would be adding hyperlinks into a block of text.
The TextBlock element has the Inlines property to allow you do that. You can add as many Inline derived elements as you like. So you can add things like plain text, richer text, hyperlinks etc.
You can do it in code, and using static xaml. However, what is more challenging is how to do it through data binding.
You would like to do the following:
<TextBlock>
<Inlines Source=”{Binding Path=blah}” />
</TextBlock>
Unfortunately, you can’t, as Inlines is not a DependencyProperty to start with.
One obvious solution is to subclass the TextBlock, and add a DependencyProperty of type List<Inline>. This works a treat, and the class is :
public class RichTextBlock : System.Windows.Controls.TextBlock
{
public static DependencyProperty InlineProperty
static RichTextBlock()
{
//OverrideMetadata call tells the system that this element wants to provide a style that is different than in base class
DefaultStyleKeyProperty.OverrideMetadata(typeof(RichTextBlock), new FrameworkPropertyMetadata(
typeof(RichTextBlock)));
InlineProperty = DependencyProperty.Register(“RichText”, typeof(List<Inline>), typeof(RichTextBlock),
new PropertyMetadata(null, new PropertyChangedCallback(OnInlineChanged)));
}
public List<Inline> RichText
{
get { return (List<Inline>)GetValue(InlineProperty); }
set { SetValue(InlineProperty, value); }
} public static void OnInlineChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue == e.OldValue)
return;
RichTextBlock r = sender as RichTextBlock;
List<Inline> i = e.NewValue as List<Inline>;
if (r == null || i == null)
return;
r.Inlines.Clear();
foreach (Inline inline in i)
{
r.Inlines.Add(inline);
}
}
}
I can’t help but feel that this should be an attached property somehow…..



You must be logged-in to post a comment. Log-in/Register