如果可以更改VisualParent,如何在UserControl中释放订阅

问题描述 投票:0回答:1

我有一个FooUserControl订阅了它的LoadedEvent。此UserControl可以放置在GUI上的其他位置(在任何Window上或任何Control的内部)。为了避免泄漏,我已经实施了某种处置方法。

此解决方案的问题:

如果将FooUserControl放在TabItemTabControl上并更改选项卡,则会调用OnVisualParentChanged()并处理订阅。如果我不添加此方法,并且您关闭了TabItem,尽管可以处置UserControl,但订阅仍在后台运行。 page也会出现同样的问题>

public class FooUserControl : UserControl
{
    private IDisposable _Subscription;
    public FooUserControl()
    {
        Loaded += _OnLoaded;
    }

    private void _OnLoaded(object sender, RoutedEventArgs e)
    {
        // avoid multiple subscribing
        Loaded -= _OnLoaded;

        // add hook to parent window to dispose subscription
        var parentWindow = Window.GetWindow(this);
        if(parentWindow != null)
            parentWindow.Closed += _ParentWindowOnClosed;

        _Subscription = MyObservableInstance.Subscribe(...);
    }

    private void _ParentWindowOnClosed(object? sender, EventArgs e)
    {
        _Dispose();
    }

    // check if the parent visual has been changed
    // can happen if you use the control on a page
    protected override void OnVisualParentChanged(DependencyObject oldParent)
    {
        if (oldParent != null)
        {
            _Dispose();
        }
        base.OnVisualParentChanged(oldParent);
    }

    private void _Dispose()
    {
        _Subscription?.Dispose();
    }
}

我有一个FooUserControl,它订阅了它的LoadedEvent。该UserControl可以放置在GUI上的其他位置(在任何Window或任何Control内部)。为避免泄漏,我已经实现了一些...

c# wpf dispose subscription
1个回答
0
投票

我终于找到了解决方案。在UnLoaded事件中,如果仍然存在实例,我将扫描Logical/VisualTree

© www.soinside.com 2019 - 2024. All rights reserved.