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

时间:2017-10-05 16:19:08

标签: c# wpf windows storyboard

我为几个朋友创建一个小应用程序。应用程序已完成,但我想让它的GUI更“专业”,所以我正在为它创建一个新的GUI。 我偶然发现了一个奇怪的问题,其中一个对话框我正在使用数据输入,有时当我使用它的Close()函数时,showDialog函数有时会抛出一个InvalidOperationException,文本“此Visual未连接到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

窗口类中的代码:

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继续运行时。如果尚未播放动画,则取消关闭并播放动画,动画在completition上再次运行Close,但animationComplete设置为true并允许窗口关闭。动画是一个简单的双重动画调整窗口高度从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设置为none,但如果我将其设置为其他内容(使用ToolWindow测试),则异常LOOKS不再发生..测试更多以查看我是否幸运或发生了什么

更新2 当windowstyle未设置为NONE时,确实看起来异常消失了。无论我是使用Windows的X按钮还是我添加的关闭窗口的按钮

触发关闭动画,都会发生这种情况

更新3 如果我没有在动画完成时关闭窗口,请隐藏它。然后在它恢复运行时在父窗口中关闭它(ShowDialog在隐藏窗口上继续显示),异常不再发生。所以,直到我发现为什么在动画完成后立即关闭它并不是所有的时间都没有窗口风格我想它是一个解决方法?因此,当WindowStyle设置为None时,与WindowStyle未设置为None时相比,Close()上会发生什么?

3 个答案:

答案 0 :(得分:0)

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

win.Show(this);

父项(产生对话框的表单)不知道它已关闭,设置此对话框的父项将通知父项它已关闭。

答案 1 :(得分:0)

我假设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没有给你&#34; X&#34;窗口右上角的关闭按钮,所以你需要担心的是你自己的关闭按钮。当你按下关闭按钮时你想要做的就是开始动画,实际上它是动画的结束,真正关闭了对话框,所以让this.Close()仅在storyboardComplete事件上发生。

答案 2 :(得分:0)

将Windowstyle设置为除None之外的任何内容都允许窗口关闭而不会被抛出,但这会使我在第一时间创建一个对话框窗口的原因已过时。

我现在发现的修复方法是在动画隐藏窗口和父窗口中关闭它后ShowDialog恢复运行时。即使WindowStyle设置为none,也不会发生异常。