2

説明

こんにちは、私はこれに関する情報をWebで検索してきましたが、修正につながるものは見つかりませんでした。

メインウィンドウが読み込まれたときにダイアログを表示したいので、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が、メニューからは機能します。

4

1 に答える 1

5

You are probably hitting this snag because the code calls ShowDialog while WPF is busy calculating layout. During layout dispatcher processing is suspended, which means that no window manager messages can be processed (and therefore you can't show a dialog, because doing that relies on messages being processed).

Normally the solution to this is to simply schedule the operation (in this instance, ShowDialog) for whenever it's possible with something like

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

However, you can't do that here because you want the result of the dialog to be provided synchronously. And you can't use Invoke because that would either throw or deadlock (I haven't tried it).

You can BeginInvoke the call to Open_Environment_Click as a whole though:

Dispatcher.CurrentDispatcher.BeginInvoke(
    new Action(() => Open_Environment_Click(null, null)));
于 2013-02-25T12:28:02.607 に答える