【问题标题】:Why does unloaded event of window do not fire in WPF?为什么在 WPF 中不触发窗口的卸载事件?
【发布时间】:2012-01-18 10:03:13
【问题描述】:

在我的 WPF 应用程序中,我创建了一个窗口并通过 ShowDialog() 方法调用它以将其显示为对话框。但是当我通过 Close() 方法关闭窗口时,不会为此对话框窗口触发 Unloaded 事件。

MyWindow obj = new MyWindow(); 
obj.ShowDialog();
obj.Close();

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    这是一个已知问题。

    改用这个

       yourWindow.Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
    
       private void Dispatcher_ShutdownStarted( object sender, EventArgs e )
       {
           //do what you want to do on closing
       }
    

    阅读this了解更多详情

    编辑

    如果上面的方法不起作用,试试这个

    yourWindow.Closing += new CancelEventHandler(YourWindow_Closing);
    
    void YourWindow_Closing(object sender, CancelEventArgs e)
    {
    
    }
    

    【讨论】:

    • 这个事件在 obj.Close() 之后也没有触发。只有在整个应用程序关闭时才会触发。
    • 是的。我创建了 Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;在对话框窗口的构造函数中,并将其事件写入上面给出的函数中。
    • 是的,更新后的答案有效!为此,我们必须使用 System.ComponentModel。谢谢 :)。但我仍然想知道为什么 Window.Unloaded() 或 Dispather.ShutdownStarted() 不起作用。是因为窗口被用作对话框吗?
    • 我仍然对这种行为感到困惑,但在谷歌搜索时,我发现人们建议为了安全起见参加闭幕式活动。在某些情况下可能会跳过卸载。这个时候我还是不知道为什么
    【解决方案2】:

    如果您真的想确认关闭,我认为最好了解窗口的生命周期及其引发的相关事件。

    但在我看来,最好的确认来源是Closed 事件。其他框架方式可能不可靠

    闭幕活动

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

    关闭在窗口关闭之前引发,它提供了一个 可以防止窗口关闭的机制。一个常见的原因 防止窗口关闭是如果窗口内容包含修改的数据。 在这种情况下,可以处理 Closing 事件来确定 数据是否脏,如果是,询问用户是否 继续关闭窗口而不保存数据或取消 窗户关闭。下面的例子显示了关键方面 处理收尾。

    更多

    Closing 事件处理程序被传递一个 CancelEventArgs,它 实现您设置为 true 的 BooleanCancel 属性以防止 从关闭的窗口。 +

    如果关闭未处理,或已处理但未取消,则 窗口将关闭。就在窗口实际关闭之前, Closed 是 提高。此时,无法阻止窗口关闭。

    注意

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

    • 用户注销或关闭 Windows。

    • 窗口的所有者关闭。

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

    • 已调用关机。

    所有窗口生命周期事件

    下图显示了窗口生命周期中主要事件的顺序。

    下图显示了在未激活的情况下显示的窗口生命周期中主要事件的顺序(在显示窗口之前将 ShowActivated 设置为 false)。

    【讨论】:

      【解决方案3】:

      我偶然发现了这个变通方法。我碰巧在我的代码中创建了另一个窗口,因此没有看到在 WPF 中未触发 Unloaded Event 的问题。

      public partial class Window1 : Window
      {
          public Window1()
          {
              InitializeComponent();
      
              new Window(); //<-- this will make Unloaded Event to trigger in WPF
          }
      }
      

      解决方法也适用于 MVVM 模式!

      如果您不使用 MVVM 模式,请忽略下面的其余代码。

      XAML (需要参考 System.Windows.Interactivity)

      <Window xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">
      
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Unloaded">
                <i:InvokeCommandAction Command="{Binding Path=DataContext.WindowUnLoadEventHandler,RelativeSource={RelativeSource AncestorType {x:Type Window}}}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
      </Window>
      

      后面的代码

          public ICommand WindowUnLoadEventHandler
          {
              get
              {
                  if (_windowUnload == null)
                  {
                      _windowUnload = new MyDelegateCommand(ExecuteWindowUnLoadEventHandler);
                  }
                  return _windowUnload;
              }
          }
      
          private void ExecuteWindowUnLoadEventHandler(object parameter)
          {
              //Do your thing
          }
      

      MyDelegateCommand

      public class MyDelegateCommand : ICommand
      {
          private readonly Action<object> _execute;
      
          public MyDelegateCommand(Action<object> execute)
          {
              this._execute = execute;
          }
      
          public void Execute(object parameter)
          {
              _execute?.Invoke(parameter);
          }
      
          public bool CanExecute(object parameter)
          {
              return true;
          }
      
          public event EventHandler CanExecuteChanged;
      }
      

      【讨论】:

      • 不幸的是,这只是因为创建一个窗口实例会将其添加为应用程序的“打开”窗口,因此应用程序将无法正常关闭
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-05
      • 2014-05-27
      • 1970-01-01
      • 2014-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多