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

C# 为什么窗口的卸载事件在WPF中不触发?,c#,wpf,C#,Wpf,在我的WPF应用程序中,我创建了一个窗口,并通过ShowDialog()方法调用它,将其显示为对话框。但是,当我通过close()方法关闭窗口时,不会为此对话框窗口触发卸载事件 MyWindow obj = new MyWindow(); obj.ShowDialog(); obj.Close(); 这是一个众所周知的问题 用这个代替 yourWindow.Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted; pri

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

MyWindow obj = new MyWindow(); 
obj.ShowDialog();
obj.Close();
这是一个众所周知的问题

用这个代替

   yourWindow.Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;

   private void Dispatcher_ShutdownStarted( object sender, EventArgs e )
   {
       //do what you want to do on closing
   }
阅读更多细节

编辑

如果以上方法无效,请尝试此方法

yourWindow.Closing += new CancelEventHandler(YourWindow_Closing);

void YourWindow_Closing(object sender, CancelEventArgs e)
{

}

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

然而,我认为最好的确认来源是
Closed
事件。其他框架方法可能不可靠

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

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

更多信息

关闭事件处理程序被传递一个CancelEventArgs,它 实现BooleanCancel属性,将该属性设置为true以防止 窗户关上了+

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

注意

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

  • 用户注销或关闭Windows

  • 窗户的主人关上了

  • 主应用程序窗口关闭,关机模式为OnMainWindowClose

  • 称为关机

所有窗口生存期事件 下图显示了窗口生存期内主要事件的顺序

下图显示了在未激活的情况下显示的窗口的生存期内主要事件的顺序(在显示窗口之前,ShowActivated设置为false)


我偶然发现了这项工作。我碰巧在代码中创建了另一个窗口,因此没有看到WPF中未触发卸载事件的问题

MyDelegateCommand

公共类MyDelegateCommand:ICommand
{
私有只读操作\u执行;
公共MyDelegateCommand(操作执行)
{
这个。_execute=execute;
}
public void Execute(对象参数)
{
_执行?.Invoke(参数);
}
公共布尔CanExecute(对象参数)
{
返回true;
}
公共事件处理程序CanExecuteChanged;
}

obj.Close()之后也不会触发此事件。它只有在整个应用程序关闭时才会启动。是。我已创建Dispatcher.ShutdownStarted+=Dispatcher\u ShutdownStarted;在对话框窗口的构造函数中,并将其事件写入上述函数中。是,更新的答案有效!为此,我们必须使用System.ComponentModel。谢谢:)。但是我仍然想知道为什么Window.unload()或Dispather.ShutdownStarted()不起作用。这是因为这个窗口被用作对话框吗?我仍然对这种行为感到困惑,但在谷歌上我发现,为了安全起见,你们建议关闭活动。在某些情况下,可能会跳过卸载。此时,我仍然不知道为什么这样做有效,因为创建一个窗口实例会将其添加为应用程序的“打开”窗口,因此应用程序将无法正常关闭
public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        new Window(); //<-- this will make Unloaded Event to trigger in WPF
    }
}
<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
    }
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;
}