2012-01-25 59 views
4

我在我的主窗口中添加了用于点击X的关闭事件的代码,并且它可以在没有问题的情况下取消事件(它通过“你确定?请务必保存”式的对话和关闭事件)处理应用程序关闭来自图标的呼叫

不幸的是,如果我的图标,双击它击中了RibbonWindow_Closing事件我的断点,但是当e.Cancel设置为true也无妨关闭了,因为如果它的被Application.Current.Shutdown()调用

Alt-F4(和图标 - >关闭)和X按钮都正确处理,但不是双击图标本身

有谁知道为什么会发生这种情况?我使用棱镜,主窗口由引导程序创建,如果它很重要。

这里是堆栈跟踪,它除了打我的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); 
     } 
    } 
} 
+0

没有摄制,很难在猜测。显示堆栈跟踪。 –

+0

@HansPassant我希望我能...从[外部代码]到我的闭幕式活动。发件人是我的壳牌窗口,我做的第一件事是设置(CancelEventArgs e)e.Cancel = true。你的意思是Repro =重现?因此,您可以在双击左上角图标时取消关闭状态? – John

+0

@HansPassant我不得不禁用调试,只是我的代码,更新OP。 – John

回答

2

好,我把范围缩小到与所述RibbonWindow控制的问题,显然它shutsdown应用当图标被双击时。

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); 
     } 
    } 
} 

我发现这里的解决方案:http://social.msdn.microsoft.com/Forums/en/wpf/thread/9955b191-13d5-4986-a5c0-e73f50a44b44

这是登记自己ApplicationClosing命令,例如:现在

[Export] 
public partial class TestShell : RibbonWindow 
{ 
    public TestShell() 
    { 
     InitializeComponent(); 

     CommandManager.RegisterClassCommandBinding(typeof(TestShell), new CommandBinding(ApplicationCommands.Close, CloseApplicationExecuted)); 
    } 

    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) 
    { 
     e.Cancel = true; 
     MessageBox.Show("Not closing 1!"); 
    } 

    private static void CloseApplicationExecuted(object sender, ExecutedRoutedEventArgs args) 
    { 
     RibbonWindow window = sender as RibbonWindow; 
     if (window != null) 
     { 
      MessageBox.Show("Not closing 2!"); 
      args.Handled = true; 
     } 
    } 
} 

,如果我双击该图标我得到“不关闭2!”,以及其他关闭方法,我得到“不关闭1!”

希望这可以节省一些人花费我的时间了解它。感谢Hans帮助我诊断问题。

更新:如果你想CloseApplicationExecuted以火一样的事件作为定期休息,只需拨打

private static void CloseApplicationExecuted(object sender, ExecutedRoutedEventArgs args) 
    { 
     RibbonWindow window = sender as RibbonWindow; 
     if (window != null) 
     { 
      args.Handled = true; 
      window.Close(); 
     } 
    } 
相关问题