Friday, December 5, 2008

 

WPF and TextDecoration

In WPF, many classes have a TextDecorations property of type TextDecorationCollection. That property is used to add any combination of overline, strike through, underline, baseline or custom decorations to text. (For the rest of this post, I will be ignoring custom and sticking with the standard four).

When using XAML, things just kind of automagically work. The following example reads very nice, and leaves not doubt that the text will be both underlined and overlined.


<TextBlock TextDecorations="Underline, Overline">
The quick red fox
</TextBlock>
 

But, when using text decorations from code, things are a bit on the weird side.

For starters, consider the following properties of the TextDecorations static class: TextDecorations.Baseline, TextDecorations.Overline, TextDecorations.Strikethrough and TextDecorations.Underline.

Sounds like a list of predefined text decorations, so what's weird with that? I find it very weird that each of those properties is actually of type TextDecprationCollection which implies it could have multiple items within the collection.

Presumably, Microsoft chose to make those properties collections so that you could directly set them in code to a TextDecorations property.


TextBlock textBlock = new TextBlock();
textBlock.TextDecorations = TextDecorations.Underlined;
 

And, they overload the TextDecorationCollection.Add() method so that it can take an IEnumerable(TextDecoration) (i.e. another TextDecorationCollection, etc.).

Now for the part I find very weird. Let's say I created a TextDecorationCollection instance and added to it TextDecorations.Underline, and then set a TextDecoration property to that collection. Then, if I add or remove TextDecorations to or from the TextDecorationCollection collection after it has already been set to the property, those changes are not rendered. One way around this is to set the property to null, add the decorations to the collection, and then set it back.


TextDecorationCollection tdc =
textBlock.TextDecorations;

textBlock.TextDecorations = null;

tds.Add(TextDecorations.Strikethrough);

textBlock.TextDecorations = tds;
 

Or, I could also create a new instance using the overload that acts like a copy constructor.



TextDecorationCollection tdc =
new TextDecorationCollection(textBlock.TextDecorations);

tds.Add(TextDecorations.Strikethrough);

textBlock.TextDecorations = tds;


 

Comments: Post a Comment





<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]