wpf中 closing事件和unload事件有啥区别?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wpf中 closing事件和unload事件有啥区别?相关的知识,希望对你有一定的参考价值。

Unloaded 在某些情况下是不会被触发的。不是amwbj说的不可靠。看你怎么处理。
比如说:Window在Closing的时候,是不会去触发它的子元素的Unloaded 事件。
如果需要确保在关闭的时候需要执行某件事情,所以你可以写一个扩展,
把它挂到Dispatcher.StartedShutdown 上去。

另,Loaded和UnLoaded和UI有关。Closing和窗体本身有关。
比如下面的情况你可以试试看。
窗口初始化的时候,如果窗口是隐藏的,那么Loaded是不会触发的。
因为它只在这个控件开始Visible的时候触发。同理,UnLoaded也是。

学习WPF的时候一定要记住UI和逻辑是跑在不同线程上的。
参考技术A unload 是不可靠的,在控件所在窗口被关闭时不会触发
closing是Window才有的,它在尝试关闭窗口的时候触发,可以选择取消这个关闭操作追问

UNLOAD 不可靠是指?unload在什么情况下触发呢?

参考技术B 楼上的回答的很对了

在可视化树中添加和删除用户控件会引发 Unloaded 事件,但不会引发 Loaded 事件

【中文标题】在可视化树中添加和删除用户控件会引发 Unloaded 事件,但不会引发 Loaded 事件【英文标题】:Adding and removing a user control from the visual tree raises Unloaded event but not Loaded event 【发布时间】:2019-09-11 02:40:47 【问题描述】:

我注意到,如果用户控件(或任何框架元素)立即从可视化树中添加和删除,则永远不会引发 Loaded 事件,但始终会引发 Unloaded 事件。

要重现该问题,请创建一个空白 UWP 项目,将以下 XAML 和代码添加到 MainPage:

<Page ...>
    <Grid>
      <StackPanel>
         <Button Click="Button_Click" Content="Click Me"/>
         <Border x:Name="border"/>
      </StackPanel>
    </Grid>
</Page>

代码背后:

public MainPage() 
     this.InitializeComponent();
     this.control = new UserControl();
     this.control.Loaded += OnLoaded;
     this.control.Unloaded += OnUnloaded;
  
  private void Button_Click(object sender, RoutedEventArgs e) 
     this.border.Child = this.control;
     this.border.Child = null;
  
  private void OnLoaded(object sender, RoutedEventArgs e) 
     System.Diagnostics.Debug.WriteLine("Loaded.");
  
  private void OnUnloaded(object sender, RoutedEventArgs e) 
     System.Diagnostics.Debug.WriteLine("Unloaded");
  

多次单击该按钮会给出以下输出:

Unloaded
Unloaded
Unloaded
Unloaded
Unloaded
Unloaded
Unloaded

FrameworkEvent.Loaded (MSDN):

在构建 FrameworkElement 并将其添加到 对象树,并准备好进行交互

FrameworkEvent.Unloaded (MSDN):

在此对象不再连接到主对象树时发生。

这里到底发生了什么?如果控件因为立即被移除而没有添加到可视化树中,为什么要调用 Unloaded 方法?有没有关于这种行为的文档?

【问题讨论】:

根据您的代码,loaded 事件不会被触发,因为它已经在您构造 UserControl 控件时重新构造 -> this.control = new UserControl(); 有一个 IsLoaded 属性,您可以检查它是否已经发生。 @Doedoe Loaded 不会在施工时被解雇。 @SeanO'Neil IsLoaded 属性仅支持最新版本的操作系统。此外,我的问题是关于(错误)行为,一种类似黑客的解决方法。 @MehrzadChehraz,你能分享一下 xaml 代码吗? 【参考方案1】:

这并不是一个真正的编程问题,而是对 Microsoft 开发人员使用的语义的批评。我打个比方来回答。我本来会对此发表评论,但它太长了。

在飞机上装载行李很慢。我必须一次做一个袋子。卸载是即时的,我拉一个杠杆,它们都掉出来了。

当我开始在飞机上装载第一件行李时,我就大喊“正在装载!” (“加载”事件)。

当我完成所有行李的装载时,我会喊“装载”。 (“加载”事件)。

如果我接到一个电话,告诉我航班被取消,我拉动控制杆并取出我已经放在那里的所有行李,然后喊“Unloaded”(“Unloaded”事件)。不管我是否真正完成了所有行李的装载,都无关紧要。我已经开始加载后卸载了它。

从语义上讲,您会看到如何卸载尚未加载的内容。将“加载”事件视为“完全加载”,将“加载”事件视为“部分加载”。无论这种行为给您带来了什么现实问题,请查看“Loading”事件而不是“Loaded”事件。

【讨论】:

感谢您的回答。这正是我的想法,但我正在寻找有助于理解它如何工作以找到优雅解决方案的文档。加载事件也不起作用。只需将 Loaded 替换为 Loading,它就不会触发。

以上是关于wpf中 closing事件和unload事件有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

WPF TabControl Unload俩次的解决方案

WPF TabControl Unload俩次的解决方案

处理 WPF 用户控件

请教wpf中的用户控件,如何模拟出它的close事件

WinForm与WPF .Close()事件

C#中winform中有啥办法区分Close()和点击窗体右上角关闭按钮来关闭窗体