窗口.已加载-ShowDialog()-无法执行操作

本文关键字:执行 操作 加载 -ShowDialog 窗口 | 更新日期: 2023-09-27 18:01:04

描述

嗨,我一直在网上搜索这方面的信息,但没有找到任何可以修复的信息。

我想在主窗口加载时显示一个对话框,因此我为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();
    }
}

例外

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

异常的详细信息如下:

    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上打开窗口,而是从菜单中打开。

窗口.已加载-ShowDialog()-无法执行操作

您可能遇到了这个问题,因为代码在WPF忙于计算布局时调用ShowDialog。在布局期间,调度程序的处理被挂起,这意味着不能处理任何窗口管理器消息(因此不能显示对话框,因为这样做依赖于正在处理的消息(。

通常情况下,解决方案是简单地安排操作(在本例中为ShowDialog(,只要有可能使用之类的东西

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

但是,这里不能这样做,因为您希望同步提供对话框的结果。您不能使用Invoke,因为这会引发或死锁(我还没有尝试过(。

您可以将BeginInvoke作为一个整体调用Open_Environment_Click,尽管:

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