在我的WPF应用程序中,我创建了一个窗口,并通过ShowDialog()方法调用它来显示它。但是当我通过Close()方法关闭窗口时,不会为此对话框窗口触发Unloaded事件。
MyWindow obj = new MyWindow();
obj.ShowDialog();
obj.Close();
答案 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
事件。其他框架方式可能不可靠
当窗口关闭时,它会引发两个事件:Closing和Closed。
在窗口关闭之前关闭,它提供了一个 可以防止窗户关闭的机制。一个常见的原因 如果窗口内容包含修改的数据,则防止窗口关闭。 在这种情况下,可以处理Closing事件以确定 数据是否是脏的,如果是,则询问用户是否要么 继续关闭窗口而不保存数据或取消 窗户关闭。以下示例显示了关键方面 处理结束。
更多
Closing事件处理程序传递一个CancelEventArgs,它就是 实现您设置为true的BooleanCancel属性以防止 关闭的窗口。 +
如果没有处理Closing,或者处理但未取消,则 窗口将关闭。就在窗口实际关闭之前,已关闭 提高。此时,无法阻止窗口关闭。
注意强>
虽然可以通过提供的机制显式关闭窗口 在非客户端和客户端区域,窗口也可以是隐式的 因应用程序的其他部分或行为而关闭 Windows,包括以下内容:
用户注销或关闭Windows。
窗口所有者关闭。
关闭主应用程序窗口,ShutdownMode为OnMainWindowClose。
调用关机。
下图显示了窗口生命周期中主要事件的顺序。
下图显示了未激活时显示的窗口生命周期中主要事件的顺序(ShowActivated在显示窗口之前设置为false)。
答案 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; }