【发布时间】:2012-01-25 15:41:56
【问题描述】:
我已经在我的主窗口上添加了用于单击 X 的 Closing 事件的代码,并且它能够毫无问题地取消该事件(它通过“你确定吗?确保保存”键入对话框和关闭事件)
不幸的是,如果我双击该图标,它会在 RibbonWindow_Closing 事件上命中我的断点,但是当 e.Cancel 设置为 true 时,它无论如何都会关闭,就好像它被 Application.Current.Shutdown() 调用一样
Alt-F4(和图标 -> 关闭)和 X 按钮都被正确处理,但没有双击图标本身
有人知道为什么会这样吗?我正在使用 Prism,如果重要的话,主窗口是由引导程序创建的。
这是堆栈跟踪,除了点击我的 RibbonWindow_Closing 事件之外,它的所有外部代码:
MyProgram.exe!MyProgram.Shell.RibbonWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) Line 64 C#
PresentationFramework.dll!System.Windows.Window.OnClosing(System.ComponentModel.CancelEventArgs e) + 0x91 bytes
PresentationFramework.dll!System.Windows.Window.WmClose() + 0x96 bytes
PresentationFramework.dll!System.Windows.Window.WindowFilterMessage(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0xe5 bytes
PresentationCore.dll!System.Windows.Interop.HwndSource.PublicHooksFilterMessage(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0x7e bytes
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0xbe bytes
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) + 0x7d bytes
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) + 0x53 bytes
WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) + 0x42 bytes
WindowsBase.dll!System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) + 0xb4 bytes
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) + 0x104 bytes
[Native to Managed Transition]
[Managed to Native Transition]
PresentationFramework.dll!System.Windows.Window.InternalClose(bool shutdown, bool ignoreCancel) + 0xa1 bytes
PresentationFramework.dll!System.Windows.Application.DoShutdown() + 0x1b6 bytes
PresentationFramework.dll!System.Windows.Application.ShutdownImpl() + 0x1c bytes
PresentationFramework.dll!System.Windows.Application.ShutdownCallback(object arg) + 0x5 bytes
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) + 0x53 bytes
WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) + 0x42 bytes
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() + 0x8d bytes
测试 RibbonWindow,给出消息但仍然关闭
<ribbon:RibbonWindow x:Class="MyProject.TestShell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
Title="TestShell" Height="300" Width="300" Closing="Window_Closing">
<Grid>
<DockPanel LastChildFill="True">
</DockPanel>
</Grid>
</ribbon:RibbonWindow>
这作为一个常规窗口工作,获取消息并保持打开状态:
<Window x:Class="MyProject.TestShell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TestShell" Height="300" Width="300" Closing="Window_Closing">
<Grid>
<DockPanel LastChildFill="True">
</DockPanel>
</Grid>
</Window>
后面的代码很简单:
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
MessageBox.Show("No close!");
}
更新
好的,我将其缩小为 RibbonWindow 控件的问题,显然它会在双击图标时关闭应用程序。
显然,如果以同样的方式关闭子窗口,它也会关闭主应用程序:http://social.msdn.microsoft.com/Forums/en/wpf/thread/3e9cdc9c-dfb7-49f2-923a-ead07504d568
/// <summary>
/// This handles the click events on the window icon.
/// </summary>
/// <param name="sender">Click event sender</param>
/// <param name="e">event args</param>
private void IconMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 1)
{
if (SystemCommands.ShowSystemMenuCommand.CanExecute(null, this))
{
SystemCommands.ShowSystemMenuCommand.Execute(null, this);
}
}
else if (e.ClickCount == 2)
{
if (ApplicationCommands.Close.CanExecute(null, this))
{
ApplicationCommands.Close.Execute(null, this);
}
}
}
【问题讨论】:
-
没有复制,很难猜。显示堆栈跟踪。
-
@HansPassant 我希望我能......它从 [外部代码] 到我的结束事件。 Sender 是我的 Shell 窗口,我要做的第一件事是设置 (CancelEventArgs e) e.Cancel = true。你的意思是复制=复制?所以双击左上角的图标可以取消关闭吗?
-
@HansPassant 我不得不只禁用调试我的代码,更新了 OP。
-
它正在被应用程序关闭,请注意跟踪中的 DoShutdown()。输出窗口中是否有任何“第一次机会异常”通知?
-
这不应该发生,窗口应该是第一个收到通知的窗口,然后应用程序关闭,因为没有剩余的窗口。如果您通过双击图标来执行此操作,我无法解释堆栈跟踪。尝试另一台机器。