wpf ShowDialog和Show有时会在关闭窗口时抛出动画异常

eqoofvh9  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(164)

我正在为几个朋友创建一个小应用程序。应用程序完成,但我想使它的GUI更“专业”,所以我做了一个新的GUI。我偶然发现了一个奇怪的问题,其中一个对话框我用于数据输入,有时当我使用关闭()函数时,showDialog函数有时会抛出一个InvalidOperationException,文本为“This Visual is not connected to a PresentationSource”。如果我在try catch中编写ShowDialog函数调用,并捕获异常以防止它停止应用程序运行时,它可以正常工作,并且有问题的窗口仍然可以按预期打开和关闭,但它有时会抛出该异常。
以对话框形式打开窗口的代码(单击按钮时从主窗口运行):

addCommand win = new addCommand();      //Creates a new instance of the window
win.Left = this.Left;                   //Makes it appear on top of the mainwindow
win.Top = this.Top + 25;

((BlurEffect)appMain.Effect).Radius = 5;//Blurs out the background (Error occurs even with this not added
win.ShowDialog();                   //Shows window as dialog (This is where the exception is thrown
((BlurEffect)appMain.Effect).Radius = 0;//Removes blur when window is closed

Window类中的代码:

private void Button_Click(object sender, RoutedEventArgs e)
{
   this.Close();
}

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
   if (!animationComplete)
   {
      Storyboard sb = Resources["closingAnimation"] as Storyboard;
      sb.Begin(this);
      e.Cancel = true;
   }
}

private void storyboardComplete(object sender, EventArgs e)
{
   animationComplete = true;
   this.Close();
}

一个按钮关闭窗口以触发ShowDialog继续运行。如果动画尚未播放,它会取消Close并播放动画,完成时再次运行Close,但animationComplete设置为true并允许窗口关闭。该动画是一个简单的doubleanimation调整窗口的高度从92到0,以创建一个“滑入,滑出”的效果在窗口上。
它的工作原理是50/50。有时它工作,其他时候它抛出异常。我不知道为什么它有时会抛出异常,有时不会。似乎是随机的。
异常的StackTrace

StackTrace  "   at System.Windows.Media.Visual.PointToScreen(Point point)\r\n   at
 Microsoft.VisualStudio.DesignTools.WpfTap.WpfVisualTreeService.Adorners.AdornerLayerWindow.UpdatePlacement()\r\n   at 
Microsoft.VisualStudio.DesignTools.WpfTap.WpfVisualTreeService.Adorners.AdornerLayerWindow.<UpdatePlacementAsync>b__77_0(Object obj)\r\n   at 
System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)\r\n   at 
System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)\r\n   at 
System.Windows.Threading.DispatcherOperation.InvokeImpl()\r\n   at 
System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)\r\n   at 
MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)\r\n   at 
System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n   at 
System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n   
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n   
at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)\r\n   
at System.Windows.Threading.DispatcherOperation.Invoke()\r\n   
at System.Windows.Threading.Dispatcher.ProcessQueue()\r\n   
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)\r\n   
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)\r\n   
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)\r\n   
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)\r\n   
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)\r\n   at 
System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)\r\n   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)\r\n   at
 MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)\r\n   at
 System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)\r\n   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)\r\n   
at System.Windows.Window.ShowHelper(Object booleanBox)\r\n   
at System.Windows.Window.Show()\r\n   
at System.Windows.Window.ShowDialog()\r\n   
at Gigglerekt_Scenebot_v2_GUI_update.MainWindow.btnAddCommand_Click(Object sender, RoutedEventArgs e) in D:\\Development\\C#\\Gigglerekt Scenebot v2 GUI update\\Gigglerekt Scenebot v2 GUI update\\MainWindow.xaml.cs:line 84\r\n   at
 System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)\r\n   at
 System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)\r\n   at 
System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)\r\n   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)\r\n   at 
System.Windows.Controls.Primitives.ButtonBase.OnClick()\r\n   at
 System.Windows.Controls.Button.OnClick()\r\n   at
 System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)\r\n   at 
System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)\r\n   at
 System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)\r\n   at 
System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)\r\n   
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)\r\n   at 
System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)\r\n   at
 System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)\r\n   at 
System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)\r\n   at 
System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)\r\n   at 
System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)\r\n   at
 System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)\r\n   at 
System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)\r\n   at 
System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)\r\n   at 
System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)\r\n   at
 System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)\r\n   at System.Windows.Input.InputManager.ProcessStagingArea()\r\n   at 
System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)\r\n   at
 System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)\r\n   at
 System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)\r\n   at
 System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)\r\n   at 
System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)\r\n   at 
MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)\r\n   at
 MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)\r\n   at 
System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)\r\n   at
 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)\r\n   at 
System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)\r\n   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)\r\n   at
 MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)\r\n   at
 System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)\r\n   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)\r\n   at
 System.Windows.Application.RunDispatcher(Object ignore)\r\n   at 
System.Windows.Application.RunInternal(Window window)\r\n   at
 System.Windows.Application.Run(Window window)\r\n   at 
System.Windows.Application.Run()\r\n   at 
Gigglerekt_Scenebot_v2_GUI_update.App.Main()"   string

更新WindowStyle设置为无,但如果我设置为其他东西(用ToolWindow测试),异常看起来不再发生了。更多的测试,看看我只是运气好还是发生了什么
更新2当windowstyle未设置为NONE时,确实看起来异常消失了。无论我是用窗口的X按钮还是我添加的关闭窗口的按钮来触发关闭动画,
更新3如果我在动画完成时没有关闭窗口,请隐藏它。然后在它恢复运行时在父窗口中关闭它(ShowDialog在隐藏窗口上继续),异常不再发生。所以直到我发现为什么在动画完成后立即关闭它并不总是工作,没有窗口风格,我猜这是一个解决办法?因此,问题是,与WindowStyle未设置为None时相比,当WindowStyle设置为None时,Close()会发生什么?

tvmytwxo

tvmytwxo1#

https://msdn.microsoft.com/en-us/library/system.windows.forms.form.show(v=vs.110).aspx

win.Show(this);

所有者(生成对话框的窗体)不知道它已关闭,为此对话框设置所有者将通知所有者它已关闭。

mpgws1up

mpgws1up2#

我假设Button_Click是关闭按钮的事件处理程序。所以,像这样修改你的代码:

private void Button_Click(object sender, RoutedEventArgs e)
{
      Storyboard sb = Resources["closingAnimation"] as Storyboard;
      sb.Completed += new EventHandler(storyboardComplete);
      sb.Begin(this);
}

private void storyboardComplete(object sender, EventArgs e)
{
   this.Close();
}

并删除Window_Closing事件处理程序。我已经有一段时间没有使用WPF了,所以我假设ShowDialog不会在窗口的右上角给你给予“X”关闭按钮,所以你需要担心的只是你自己的关闭按钮。当他们按下关闭按钮时,您要做的是启动动画,实际上是动画的结束才真正关闭对话框,因此让this.Close()只发生在storyboardComplete事件中。

tsm1rwdh

tsm1rwdh3#

将Windowstyle设置为None以外的任何值都允许窗口关闭而不会抛出异常,但这将使我首先为dialog创建窗口的原因变得过时。
我现在找到的修复方法是让动画隐藏窗口,并在ShowDialog恢复运行时在父窗口中关闭它。即使WindowStyle设置为none,也不会发生异常。

相关问题