Hi, I've been searching the web for information on this and didn't find anything that would lead to it being fixed.
I want to show a dialog when my main window loads and thus I assigned an event handler to my MainWindow
's Loaded event. The handler is as follows:
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
is an event handler for a menu item, and is written as follows:
private void Open_Environment_Click(object sender, RoutedEventArgs e) {
SelectEnvironmentDialog dialog = new SelectEnvironmentDialog(Environments);
if (dialog.ShowDialog().Value == true) {
dialog.SelectedEnvironment.Open();
}
}
The exception occurs when I call the ShowDialog
of dialog in Open_Environment_Click
.
The details on the exception are as follows:
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:
The interesting part is that I do not get the error when I call Show on a new window inside the MainWindow
's constructor, maintaining the above code (just adding this line in the constructor):
new GotoDialog().Show();
Note that I did not shorten any of the code provided, ShowDialog
is not custom and not opening the window on Loaded
but from the menu works.
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)));