【问题标题】:Unsubscribing events in WPF Control取消订阅 WPF 控件中的事件
【发布时间】:2011-04-14 20:21:26
【问题描述】:

我有一个自定义控件,一个范围滑块,在我的一个视图中使用。

构造函数如下所示:

        EventHandler ReCalculateWidthsHandler;
        public RangeSlider()
        {
            ReCalculateWidthsHandler = OnReCalculateWidths;
            DependencyPropertyDescriptor.FromProperty(ActualWidthProperty, typeof(RangeSlider)).
                AddValueChanged(this, ReCalculateWidthsHandler);
        }

我不知道何时/如何取消订阅该事件处理程序。 Control 中没有 Dispose 方法。有什么方法可以通知我控件正在被释放/删除,以便我可以取消订阅任何订阅的事件?

这可能是一个更普遍的问题:给定一个扩展 Control 的自定义控件,您如何知道它何时被释放?

谢谢。

【问题讨论】:

    标签: wpf wpf-controls dispose


    【解决方案1】:

    通常,您应该使用OverrideMetadata 为依赖属性添加更改处理程序。不幸的是,它不适用于只读属性。这就是我认为你使用属性描述符的原因。您知道这种方式太复杂了,因为 AddValueChanged 存储了导致内存泄漏的静态强引用。我认为您应该从SizeChanged 事件中调用 ReCalculateWidthsHandler,而不是订阅属性描述符。

    【讨论】:

    • 如果我将其更改为定期订阅 SizeChanged 事件,当控件被释放时,我将在哪里取消订阅该事件?如果我不退订,我会不会出现内存泄漏?
    • 没有。如果您为同一实例的事件订阅处理程序,则不会有外部引用。
    • 啊,是的。这让我不以为然。假设另一个控件被传递给我的自定义控件,并且我的自定义控件订阅了它的一个事件,类似于 otherControl.SomeEvent += SomeEventHandler。我的自定义控件何时会取消订阅该事件,以便不保留对 otherControl 的引用?
    • WPF 中没有一个具体的退订点。当我需要引用另一个控件时,我声明依赖属性并使用绑定。依赖属性为您提供更改通知,您可以在其中管理订阅,而 Binding 持有弱引用并反映可视树更改。最后一个允许您在引用因树更改而变得无效时做出反应并取消订阅事件(在属性更改处理程序中)。
    猜你喜欢
    • 2018-01-05
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    • 2011-08-14
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多