首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Wpf管理资源清理

Wpf管理资源清理
EN

Stack Overflow用户
提问于 2014-04-20 19:47:40
回答 2查看 2.6K关注 0票数 1

我正在努力寻找一种清理自定义控件可能生成的非托管资源的好方法。在这种情况下,父窗口打开一个具有非托管资源的自定义控件的子窗口(请参阅下面的代码)。当不再使用CustomControl时,需要清理这些资源,即当它所在的树卸载时(即子窗口关闭),或者从树中删除它(即它本身是卸载的)。

方法1:在手动关闭子窗口时触发卸载事件,但如果关闭父窗口(其父窗口会自动关闭子窗口),则不会触发该事件。

方法2: OnVisualChildrenChanged --当子窗口由父窗口手动或自动关闭时,只在将CustomControl移动到不同的父元素时才会调用。

方法3: Dispatcher.ShutdownStarted --这实际上没有多大帮助,因为用户在完成应用程序之前可能已经打开/关闭了几个子窗口,并且只在最后清理内存是不够的。

方法4:让CustomControl订阅ChildWindow.Closing --这也不够好,.控件不应该知道它在窗口中。

方法5:终结器与方法3有相同的问题。它可能需要一段时间才能被调用

代码语言:javascript
复制
public class CustomControlWithManagedResources : Control
{
    ~CustomControlWithManagedResources()
    {
        Console.WriteLine("~CustomControlWithManagedResources");
    }

    public CustomControlWithManagedResources()
    {
        Unloaded += CustomControl_Unloaded;
        Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
    }

    void Dispatcher_ShutdownStarted(object sender, EventArgs e)
    {
        Console.WriteLine("ShutdownStarted");
    }

    void CustomControl_Unloaded(object sender, RoutedEventArgs e)
    {
        Console.WriteLine("Unloaded");
    }

    protected override void OnVisualParentChanged(DependencyObject oldParent)
    {
        base.OnVisualParentChanged(oldParent);

        if(oldParent != null)
            Console.WriteLine("OnVisualParentChanged");
    }
}

public class ChildWindow : Window
{
    public ChildWindow()
    {
        Content = new CustomControlWithManagedResources();
    }
}

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    protected override void OnMouseDoubleClick(MouseButtonEventArgs e)
    {
        base.OnMouseDoubleClick(e);
        new ChildWindow() { Owner = this }.Show();
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-21 15:44:12

在WPF应用程序中这样做的正确方法是使用MVVM模式,并将视图(控件)中的所有逻辑和依赖项移除到ViewModels中。

您的父ViewModel将创建一个实现IDisposable的子ViewModel,然后当它移除子ViewModel时,它将在子ViewModel上调用Dispose

如果您的主ViewModel有需要清理的非托管资源,那么它应该实现IDisposable和创建它的引导程序,它应该负责清理它们。

另一个很好的参考是Caliburn.Micro

票数 2
EN

Stack Overflow用户

发布于 2014-04-21 09:35:43

你好像在要求闭幕式。

看一看这个:

事件(v=vs.110).aspx

当窗口关闭时,它会引发两个事件:关闭和关闭。

虽然可以通过非客户端和客户端区域中提供的机制显式关闭窗口,但由于应用程序或Windows的其他部分的行为,窗口也可以隐式关闭,包括:

用户注销或关闭Windows。

窗口的所有者关闭(见所有者)。

主应用程序窗口关闭,ShutdownMode为OnMainWindowClose。

就叫关机。

在所有这些场景中,闭幕式和闭幕式将被称为。

不要将控件订阅到Window.Closing事件。让窗户来做这件事。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23186850

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档