Processing applications Closing calls from the icon

I added the code for the Closing event in my main window, which works for clicking on X, and it can cancel the event without problems (it goes through "are you sure?" Make sure you saved, the type of dialog and the closing event)

Unfortunately, if I double-click the icon, it will hit my breakpoint in the RibbonWindow_Closing event, but when e.Cancel set to true, it still closes, as if it had been called Application.Current.Shutdown()

Alt-F4 (and the icon → close), and the X button is processed correctly, but not by double-clicking on the icon itself

Does anyone know why this will happen? I use Prism, and the main window is created by the bootloader, if that matters.

Here is the stack trace, all its external code, except for hitting my RibbonWindow_Closing event:

 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 

Testing RibbonWindow, gives a message, but still closes

 <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> 

This works like a regular window, Receives a message, and it remains open:

 <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> 

The code behind is simple:

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

Update

Ok, I narrowed it down to a problem with the RibbonWindow control, apparently it shuts down the application when the icon is double-clicked.

Apparently, it also closes the main application if the same window is closed: 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); } } } 
+4
source share
1 answer

Ok, I narrowed it down to a problem with the RibbonWindow control, apparently it shuts down the application when the icon is double-clicked.

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

I found a solution here: http://social.msdn.microsoft.com/Forums/en/wpf/thread/9955b191-13d5-4986-a5c0-e73f50a44b44

which was supposed to register my own ApplicationClosing command, for example:

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

Now, if I double-click the icon, I get "Do not close 2!", And any other closing method I get "Do not close 1!"

Hope this can save someone how much it took me to figure this out. Thanks, Hans for helping diagnose the problem.

Update. If you want the CloseApplicationExecuted function to fire the same event with regular closure, just call

 private static void CloseApplicationExecuted(object sender, ExecutedRoutedEventArgs args) { RibbonWindow window = sender as RibbonWindow; if (window != null) { args.Handled = true; window.Close(); } } 
+2
source

Source: https://habr.com/ru/post/1392970/


All Articles