是否有一种聪明的方法来检测窗口是否被
关闭我想在window.Closing处理程序中检测到这一点。 每当我调用window.Close()时,我都可以设置一个标志,但这不是一个非常漂亮的解决方案。
答案 0 :(得分:14)
我不确定我喜欢这个,但这是一个你明显有理由问的问题。如果您要在OnClosing事件中获取堆栈跟踪,则可以查找Window.Close事件。
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
bool wasCodeClosed = new StackTrace().GetFrames().FirstOrDefault(x => x.GetMethod() == typeof(Window).GetMethod("Close")) != null;
if (wasCodeClosed)
{
// Closed with this.Close()
}
else
{
// Closed some other way.
}
base.OnClosing(e);
}
答案 1 :(得分:3)
不同之处如下:
Window.Close()会导致WM_CLOSE被发送到窗口。
Alt + F4和X按钮导致WM_SYSCOMMAND消息具有SC_CLOSE类型。您可以决定是否希望进一步路由此消息(并最终导致WM_CLOSE)。
这是捕获此消息的一段代码。如果您想取消默认行为,请从委托中返回“True”:
class SystemMenu : IDisposable
{
const int WM_SYSCOMMAND = 0x0112;
const int SC_CLOSE = 0xF060;
public delegate bool HandleSystemCommand();
HwndSource _source;
HandleSystemCommand _handler;
public SystemMenu(Window window, HandleSystemCommand handler )
{
_handler = handler;
_source = HwndSource.FromHwnd(new WindowInteropHelper( window ).Handle);
_source.AddHook(WndProc);
}
public void Dispose() {
_source.RemoveHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case WM_SYSCOMMAND:
int command = wParam.ToInt32() & 0xfff0;
if (command == SC_CLOSE)
handled = _handler();
break;
default:
break;
}
return IntPtr.Zero;
}
}