取消

WPF 窗口和控件的 Unloaded 事件什么情况下不会触发

WPF 中如果监听窗口或者控件的的 Unloaded 事件,那么这个事件会触发吗?答案是不确定的。


示例代码

1
2
3
4
5
6
<Window x:Class="Walterlv.TempDemo.Wpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        Unloaded="Window_Unloaded" Closed="Window_Closed">
    <Grid Unloaded="Grid_Unloaded">
    </Grid>
</Window>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void Window_Unloaded(object sender, RoutedEventArgs e)
{
    // 断点 1
}

private void Grid_Unloaded(object sender, RoutedEventArgs e)
{
    // 断点 2
}

private void Window_Closed(object sender, EventArgs e)
{
    // 断点 3
}

你觉得以上事件中,断点都会进入吗?

不确定的答案

在微软的官方文档中说:

Note that the Unloaded event is not raised after an application begins shutting down. Application shutdown occurs when the condition defined by the ShutdownMode property occurs. If you place cleanup code within a handler for the Unloaded event, such as for a Window or a UserControl, it may not be called as expected.

如果应用程序正在关闭,那么 Unloaded 时间将不会触发。WPF 通过设置在 Application 上的 ShutdownMode 来决定是否在关闭窗口后关闭应用程序。因此,如果你试图通过在 Unloaded 事件中执行清理操作,那么可能不会如预期般完成。

因此,一般情况下,Unloaded 事件是会触发的,但满足如下任一情况时,此事件将不不会触发:

  1. Application.ShutdownMode="OnLastWindowClose" 且最后一个窗口关闭时;
  2. Application.ShutdownMode="OnMainWindowClose" 且主窗口关闭时。

顺序

当触发 Unloaded 事件时,以上事件的触发顺序为:

  • 断点 3
  • 断点 1
  • 断点 2

参考资料

本文会经常更新,请阅读原文: https://blog.walterlv.com/post/wpf-unloaded-event-not-fired.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected])

登录 GitHub 账号进行评论