Window.Loaded - ShowDialog() - 无法执行操作

时间:2013-02-25 12:17:30

标签: c# wpf invalidoperationexception showdialog

描述

嗨,我一直在网上搜索有关这方面的信息,但没有发现任何可能导致修复的内容。

我想在我的主窗口加载时显示一个对话框,因此我为我的MainWindow的Loaded事件分配了一个事件处理程序。处理程序如下:

private void Window_Loaded(object sender, RoutedEventArgs e) {
    if (Settings.Instance.GetBool(ConfigFunctionalityGroup, "CheckForUpdatesOnStartup")) {
        worker = new BackgroundWorker();
        worker.DoWork += worker_DoWork;
        worker.ProgressChanged += worker_ProgressChanged;
        worker.WorkerReportsProgress = true;
        worker.RunWorkerAsync();
    }

    findandreplacedialog = new FindAndReplaceDialog() { Owner = this };

    Open_Environment_Click(null, null);
}

Open_Environment_Click是菜单项的事件处理程序,编写如下:

private void Open_Environment_Click(object sender, RoutedEventArgs e) {
    SelectEnvironmentDialog dialog = new SelectEnvironmentDialog(Environments);

    if (dialog.ShowDialog().Value == true) {
        dialog.SelectedEnvironment.Open();
    }
}

异常

当我在ShowDialog中调用Open_Environment_Click对话框时发生异常。

例外的细节如下:

    System.InvalidOperationException was unhandled
  HResult=-2146233079
  Message=Cannot perform this operation while dispatcher processing is suspended.
  Source=WindowsBase
  StackTrace:
       at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       at System.Windows.Window.ShowHelper(Object booleanBox)
       at System.Windows.Window.Show()
       at System.Windows.Window.ShowDialog()
       at UnrealSed.MainWindow.Open_Environment_Click(Object sender, RoutedEventArgs e) in c:\Users\ZéLuís\Documents\Visual Studio 2012\Projects\Unreal Sed\UnrealSed\MainWindow.xaml.cs:line 610
       at UnrealSed.MainWindow.Window_Loaded(Object sender, RoutedEventArgs e) in c:\Users\ZéLuís\Documents\Visual Studio 2012\Projects\Unreal Sed\UnrealSed\MainWindow.xaml.cs:line 89
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
       at System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent)
       at System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(Object root)
       at MS.Internal.LoadedOrUnloadedOperation.DoWork()
       at System.Windows.Media.MediaContext.FireLoadedPendingCallbacks()
       at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
       at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
       at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
       at System.Windows.Media.MediaContext.Resize(ICompositionTarget resizedCompositionTarget)
       at System.Windows.Interop.HwndTarget.OnResize()
       at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(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 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, 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)
       at MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.HwndSubclass.DefWndProcWrapper(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
  InnerException: 

进一步详情

有趣的是,当我在MainWindow的构造函数中的一个新窗口上调用Show时,我没有得到错误,维护上面的代码(只是在构造函数中添加这一行):

new GotoDialog().Show();

请注意,我没有缩短所提供的任何代码,ShowDialog不是自定义的,也没有在Loaded上打开窗口,而是从菜单中运行。

1 个答案:

答案 0 :(得分:3)

你可能会遇到这个障碍因为代码在WPF忙于计算布局时调用ShowDialog。在布局调度程序处理暂停期间,这意味着不能处理任何窗口管理器消息(因此您无法显示对话框,因为这样做依赖于正在处理的消息)。

通常情况下,解决方法是简单地安排操作(在本例中为ShowDialog),以便在任何可能的情况下安排

Dispatcher.CurrentDispatcher.BeginInvoke((Action)(...));

但是,您无法在此处执行此操作,因为您希望同步提供对话框的结果。并且你不能使用Invoke,因为它会抛出或死锁(我还没试过)。

您可以BeginInvoke整个Open_Environment_Click来电:

Dispatcher.CurrentDispatcher.BeginInvoke(
    new Action(() => Open_Environment_Click(null, null)));