I have simple WPF application with a main window and a child window. The child window should ask for confirmation on close.
public partial class MainWindow : Window
{
Window childWindow;
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
childWindow = new Window();
childWindow.Owner = this;
childWindow.Closing += ChildWindow_Closing;
childWindow.Show();
}
private void ChildWindow_Closing(object sender, CancelEventArgs e)
{
MessageBox.Show(childWindow, "Close child window?");
}
}
When confirmation dialog is shown if click "Show desktop" on taskbar and then click "Show open windows", app will be crashed with exception:
System.InvalidOperationException occurred
HResult=0x80131509
Message=Cannot set Visibility to Visible or call Show, ShowDialog, Close, or WindowInteropHelper.EnsureHandle while a Window is closing.
Source=PresentationFramework
StackTrace:
at System.Windows.Window.VerifyNotClosing()
at System.Windows.Window.CoerceVisibility(DependencyObject d, Object value)
at System.Windows.DependencyObject.ProcessCoerceValue(DependencyProperty dp, PropertyMetadata metadata, EntryIndex& entryIndex, Int32& targetIndex, EffectiveValueEntry& newEntry, EffectiveValueEntry& oldEntry, Object& oldValue, Object baseValue, Object controlValue, CoerceValueCallback coerceValueCallback, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, Boolean skipBaseValueChecks)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.Window.UpdateVisibilityProperty(Visibility value)
at System.Windows.Window.WmShowWindow(IntPtr wParam, IntPtr lParam)
at System.Windows.Window.WindowFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
If replace owner of MessageBox dialog to the main window (to "this"), the exception isn't occurs.
What here can be wrong?
Can you post your XAML code? See below what I have in MainWindow.xaml, copied your code into MainWindow.cs and the app complies and runs ok.
<Window x:Class="WpfApp2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
</Grid>
Sorry this is not much of a help, can't reproduce your exception.
Edit: Another thought, you might try using
childWindow.ShowDialog();
Further edit:
Based on your comment I found what causes the exception. Prior using the 'Show Desktop' function, there are two app windows opened in the taskbar. Subsequently, when trying to restore the app from taskbar, the child window is no longer visible. It seems that Windows makes a judgement call, losing the closing child window in advance. So when you click on the main window thumbnail, the app tries to bring into view the parent window but is unable to set its visibility, whilst there is its child in closing process.
There may be few approaches to this, but hiding the child window while closing may be one of them. Alternatively you could temporarily hide the main window instead, this also prevents the exception. The former solution gives the visibility back to the parent window, assuming the child window will be closed (if not set it to visible again), the latter leaves the child window the only visible window and it forces Windows to show its thumbnail in taskbar.
private void ChildWindow_Closing(object sender, CancelEventArgs e)
{
childWindow.Visibility = Visibility.Hidden;
MessageBox.Show(childWindow, "Close child window?");
}
or
private void ChildWindow_Closing(object sender, CancelEventArgs e)
{
Visibility = Visibility.Hidden;
MessageBox.Show(childWindow, "Close child window?");
Visibility = Visibility.Visible;
}
User contributions licensed under CC BY-SA 3.0