我有一个简单的WPF应用程序,它有一个主窗口和一个子窗口。子窗口应该在关闭时要求确认。
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?");
}
}
如果显示确认对话框,如果单击任务栏上的“显示桌面”,然后单击“显示打开的窗口”,则应用程序将崩溃,但例外情况为:
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)
如果将MessageBox对话框的所有者替换为主窗口(“this”),则不会发生异常。
这可能是错的?
答案 0 :(得分:1)
你可以发布你的XAML代码吗?请参阅下面我在MainWindow.xaml中的内容,将您的代码复制到MainWindow.cs中,该应用程序符合并运行正常。
<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>
很抱歉,这不是一个很大的帮助,无法重现您的例外。
编辑:另一个想法,你可以尝试使用
childWindow.ShowDialog();
进一步编辑:
根据您的评论,我找到了导致异常的原因。之前使用“显示桌面”&#39;功能,任务栏中打开了两个应用程序窗口。随后,当尝试从任务栏恢复应用程序时,子窗口不再可见。似乎Windows会进行判断调用,提前丢失关闭的子窗口。因此,当您单击主窗口缩略图时,应用程序会尝试进入父窗口但无法设置其可见性,同时其子项处于关闭过程中。
可能没有什么方法可以解决这个问题,但在关闭时隐藏子窗口可能就是其中之一。或者,您可以暂时隐藏主窗口,这也可以防止异常。前一个解决方案将可见性返回到父窗口,假设子窗口将关闭(如果未将其设置为再次可见),后者将子窗口保留为唯一可见窗口,并强制Windows在任务栏中显示其缩略图。
private void ChildWindow_Closing(object sender, CancelEventArgs e)
{
childWindow.Visibility = Visibility.Hidden;
MessageBox.Show(childWindow, "Close child window?");
}
或
private void ChildWindow_Closing(object sender, CancelEventArgs e)
{
Visibility = Visibility.Hidden;
MessageBox.Show(childWindow, "Close child window?");
Visibility = Visibility.Visible;
}