I'm trying to add a TextDecoration (e.g. Strikethrough) to a TextBlock via a data bound property.
Minimal example:
public partial class TextDecoTest : Window
{
public TextDecoTest()
{
DataContext = this;
InitializeComponent();
TextDeco.Add(TextDecorations.Strikethrough); //Exception here
}
public TextDecorationCollection TextDeco
{
get { return (TextDecorationCollection)GetValue(TextDecoProperty); }
set { SetValue(TextDecoProperty, value); }
}
public static readonly DependencyProperty TextDecoProperty =
DependencyProperty.Register("TextDeco", typeof(TextDecorationCollection), typeof(TextDecoTest), new PropertyMetadata(new TextDecorationCollection()));
}
XAML:
<Window>
<TextBlock Text="Test" TextDecorations="{Binding TextDeco}" />
</Window>
However, adding of a TextDecoration fails with:
Specified value of type 'System.Windows.TextDecorationCollection' must have IsFrozen set to false to modify.
Okay, but since you can't really unfreeze controls in WPF, I'm a bit stumped. It works if I create a new TextDecorationCollection, add the decoration and then replace the entire collection, but this isn't really feasible in our case and also feels wrong. I found several other mentions of this issue, but they seem to refer to a bug that has been fixed with .NET 4.5 (we're using 4.6.1).
The four static properties in the TextDecorations
class are already of type TextDecorationCollection
, e.g.
public static TextDecorationCollection Strikethrough { get; }
Apparently they aren't meant to be combined.
So instead of adding any of them to your TextDeco
property, just set the property like this:
TextDeco = TextDecorations.Strikethrough;
You may however combine two TextDecorations like this:
TextDeco = new TextDecorationCollection(
Enumerable.Concat(TextDecorations.Strikethrough, TextDecorations.Underline));
Or more, by recursively calling Concat:
TextDeco = new TextDecorationCollection(
Enumerable.Concat(TextDecorations.Strikethrough,
Enumerable.Concat(TextDecorations.Underline, TextDecorations.OverLine)));