65.9K
CodeProject 正在变化。 阅读更多。
Home

依赖属性的更改通知

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2009 年 4 月 1 日

CC (Attr 3U)

3分钟阅读

viewsIcon

58624

依赖属性的更改通知

前几天,我在WPF中进行开发时,决定需要在控件的可见性属性更改时执行某些特定操作。您可能知道,大多数WPF控件的属性都有一个相应的<PropertyName>Changed事件,例如IsEnabled/IsEnabledChanged和(有趣的是)IsVisible/IsVisibleChanged,但是(出于某种原因)没有Visibility

所以,这些仅仅是依赖属性,依赖属性的重点是更改通知,因此肯定有一种方法可以找出何时更改了依赖属性的值。当我在WPF中遇到困难时,我通常会向我的好朋友兼同事Paul Jackson寻求帮助。Paul很忙,但他指明了正确的方向,稍后我快速搜索后找到了Ben Constable的帖子“依赖属性的巧妙技巧”。Ben描述的是使用DependencyPropertyDescriptor类和AddValueChanged方法,如下面的代码示例所示。

DependencyPropertyDescriptor descriptor =
    DependencyPropertyDescriptor.FromProperty(
        UIElement.VisibilityProperty,
        typeof(UIElement));
descriptor.AddValueChanged(this.hiddenPanel,
    new EventHandler(hiddenPanel_VisibilityChanged));

这两行代码为名为hiddenPanel的面板的Visibility属性创建了一个DependencyPropertyDescriptor,然后添加hiddenPanel_VisibilityChanged作为值更改时的事件处理程序。 bingo!问题解决了。事实证明,这并不是我需要采取的方法,由于更好地理解了问题空间,我以不同的方式解决了这个问题。

但是,与Paul和我讨论的大多数事情一样,我们打开了一个潘多拉魔盒,不得不进一步挖掘。正如Paul在他的关于此主题的帖子中指出的那样(他抢在我前面!),这种方法有两个问题。

  1. 您只向AddValueChanged方法提供一个EventHandler,这意味着您无法访问先前和新的值。
  2. 除非您在完成所有操作后调用RemoveValueChanged方法,否则此解决方案可能会导致内存泄漏。您可以想象,对于更复杂的场景,这可能会更加困难。

事实证明,Paul的挖掘发现了一篇非常聪明的Andrew Smith的文章,其中描述了使用Paul最初建议的所有元素来解决此问题的完整解决方案(拼写错误都是他的;))

(13:40) Paul Jackson
因此,使用描述符方法的缺点是您无法获得“旧”和“新”值信息。因此,即使只需几行代码就可以收到通知,但信息量也不大。
另一种方法也不太吸引人,那就是使用数据绑定:创建您自己的DP,启用更改通知,然后将该属性绑定到您真正想要接收通知的源。

(13:43) Paul Jackson
为了清理它,您可以从目标控件继承并通过覆盖属性元数据并调用您自己的事件来引发必要的通知——听起来比实际情况更糟糕,这实际上非常干净,并且如果添加一些泛型,可以成为一个优雅的解决方案(还不知道,因为我还没有尝试过)。

(13:45) Paul Jackson
底线是此版本的WPF不会公开该信息——弄清楚描述符机制和数据绑定机制如何实现通知会很有趣(因为它们似乎实际上只对DP的所有者内部可见)。

如果您查看Andrew的文章,您可以看到它们都“殊途同归”。 :)

此时,我已经证明了最初的方法有效,使用了完全不同的方法来解决我的问题,而无需诉诸依赖属性更改通知,然后继续进行。但是,Paul已经写博客介绍了相同的问题,并提出了他自己的解决方案,该解决方案“*简单易于实现*”。因此,如果您需要此问题的解决方案,请查看。

kick it on DotNetKicks.com

© . All rights reserved.