以编程方式将TextDecoration添加到TextBlock会导致InvalidOperationException

时间:2016-12-12 13:29:18

标签: c# wpf textblock invalidoperationexception

我正在尝试通过数据绑定属性将TextDecoration(例如删除线)添加到TextBlock。

最小例子:

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>

但是,添加TextDecoration失败了:

  

'System.Windows.TextDecorationCollection'类型的指定值必须   将IsFrozen设置为false以进行修改。

好的,但是因为你无法真正解冻WPF中的控件,我有点难过。它可以工作,如果我创建一个新的TextDecorationCollection,添加装饰,然后替换整个集合,但这在我们的情况下是不可行的,也感觉不对。 我发现了其他几个关于这个问题的提及,但它们似乎是指用.NET 4.5修复的一个错误(我们使用的是4.6.1)。

1 个答案:

答案 0 :(得分:0)

TextDecorations类中的四个静态属性已经是TextDecorationCollection类型,例如

public static TextDecorationCollection Strikethrough { get; }

显然他们不打算合并。

因此,不要将任何属性添加到TextDeco属性中,只需设置如下属性:

TextDeco = TextDecorations.Strikethrough;

然而,您可以组合两个TextDecorations,如下所示:

TextDeco = new TextDecorationCollection(
    Enumerable.Concat(TextDecorations.Strikethrough, TextDecorations.Underline));

或者更多,通过递归调用Concat:

TextDeco = new TextDecorationCollection(
    Enumerable.Concat(TextDecorations.Strikethrough,
        Enumerable.Concat(TextDecorations.Underline, TextDecorations.OverLine)));