如何在现有的依赖属性回调中添加逻辑?

14

我正在尝试向UIElement.RenderTransformOriginProperty添加PropertyChangedCallback。当我尝试覆盖PropertyMetadata时,会抛出异常。

我已经在MSDN和Google上搜索了,但我只找到了这篇文章。在该帖子中的某些地方建议使用DependencyPropertyDescriptor.AddValueChanged,但这不会解决我的问题,因为这不是每个实例的回调函数。

我完全不理解这个异常是什么意思。有人知道我做错了什么吗?

public class foo : FrameworkElement
{
    private static void Origin_Changed( DependencyObject d,
                                        DependencyPropertyChangedEventArgs e)
    { }

    static foo()
    {
        PropertyMetadata OriginalMetaData =
            UIElement.RenderTransformOriginProperty.GetMetadata(
                typeof(FrameworkElement));



/*An exception is thrown when this line is executed:
 "Cannot change property metadata after it has been associated with a property"*/
        OriginalMetaData.PropertyChangedCallback +=
            new PropertyChangedCallback(Origin_Changed);



        UIElement.RenderTransformOriginProperty.OverrideMetadata(
            typeof(foo), OriginalMetaData);
    }
}
1个回答

27

当您调用OverrideMetadata时,WPF将为您合并属性元数据,无需将原始元数据对象传递给它。因此,您所要做的就是

UIElement.RenderTransformOriginProperty.OverrideMetadata(typeof(foo), new PropertyMetadata(new PropertyChangedCallback(Origin_Changed)));

需要注意的一件事情是,有时候上述代码会抛出异常。发生这种情况的两种情况是:

1. 原始元数据是PropertyMetadata的子类 - 我见过FrameworkPropertyMetadata和UIPropertyMetadata。每种情况下都需要使用相应的元数据。

2. 该依赖属性是只读的,你无法对其进行任何操作。


太棒了!谢谢!我倾向于认为框架不会自动为我完成那种工作。我想这只是在高级主导时代成为低级工程师的职业风险...... - Giffyguy
呵呵,我能理解那种感受。当我无法理解“合法”的WPF方式时,我花费了无数个小时试图从Win32程序员的角度来理解WPF。 - Igor Zevaka
关于您的编辑:哦,这有点让我困惑 - 我需要监听一些只读的FrameworkElement依赖属性的更改。在这种情况下,您会建议什么?我真的,真的不想尝试在我的类的每个实例上使用AddValueChanged来实现它。虽然,我猜我也不介意,只要它没有任何性能损失 - 相对于PropertyChangedCallback。唉,这必须是高效的,无论如何。 - Giffyguy
2
当我说只读时,我的意思是依赖属性元数据不能被覆盖。如果尝试调用OverrideMetadata,则会引发异常。如果是这种情况,恐怕你无能为力。 - Igor Zevaka
这段代码放在哪里有关系吗? 例如,我能否在我的WPF应用程序中的某个对象中创建一个静态构造函数,并在编译时使用默认设置将元数据与框架中的元数据合并, 还是必须子类化我想要影响的FrameworkElement? - eran otzap
你可以查看这个 Stack Overflow 的问题,以了解你需要放置上述代码的位置。 - Murat Aykanat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接