为什么窗口的卸载事件不会在WPF中触发?

时间:2012-01-18 10:03:14

标签: c# wpf

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

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

3 个答案:

答案 0 :(得分:11)

这是一个已知问题。

改为使用

   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)
{

}

答案 1 :(得分:2)

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

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

结束事件

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

  

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

更多

  

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

     

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

注意

  

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

     
      
  • 用户注销或关闭Windows。

  •   
  • 窗口所有者关闭。

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

  •   
  • 调用关机。

  •   

所有窗口生命周期事件

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

enter image description here

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

enter image description here

答案 2 :(得分:0)

我偶然发现了这种解决方法。我碰巧在代码中创建了另一个窗口,因此没有看到在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;
}