I am using this wonderful framework for doing modal dialogs in WPF.
Using this framework, I am trying to get a modal dialog to overlay another modal dialog when a user clicks a button from within the first dialog. There is an example of this in the DemoApp
for this framework which just uses the _dialogmanager
to first pop up one MessageDialog
and then another.
The code that does this from the DemoApp
looks like this:
private void ShowLayeredDialog()
{
_dialogManager
.CreateMessageDialog("Wait 2 secs...", "I'm the 1st dialog", DialogMode.Ok)
.Show();
ThreadPool.QueueUserWorkItem(o =>
{
Thread.Sleep(2000);
_dialogManager
.CreateMessageDialog("Hello again...", "I'm the 2nd dialog", DialogMode.Ok)
.Show();
});
}
I tried to do something similar but instead of using the method call to CreateMessageDialog, I wanted to use their CreateCustomContentDialog()
, which takes an object and displays its contents (provided its a UIElement
) in a modal view.
So, having already called the _dialogManager
to get me into the first modal view, I created a button on that view that would spawn a new CustomContentDialog like so using a technique similar to their DemoApp code:
ThreadPool.QueueUserWorkItem(o => _dialogManager.CreateCustomContentDialog(new SpikePhaseView(), DialogMode.Ok).Show());
Unfortunately, I get the exception 'The calling thread must be STA, because many UI components require this' on the constructor for SpikePhaseView()
, which is a vanilla UserControl.
So having researched this error here and here I implemented the un-accepted, but highly up-voted solution from the second link of setting the ApartmentState(ApartmentState.STA) like so:
var test = new Thread(() => _dialogManager.CreateCustomContentDialog(new SpikePhaseView(), DialogMode.Ok).Show());
test.SetApartmentState(ApartmentState.STA);
test.Start();
But then somewhere down WpfDialogManagment framework code, I get this error 'The calling thread cannot access this object because a different thread owns it.' on this block of code:
public void SetCustomContent(object content)
{
CustomContent.Content = content;
}
Above, the CustomContent (A System.Windows.Controls.ContentControl) is being set to my SpikePhaseView object.
Edit
In the DemoApp they are able to launch two modal dialogs successfully (without error). Why can't I have one UserControl (view) spawn another without having this conflict over which thread is setting the content of this CustomContext object?
It seems like setting the ApartmentState helped get me past the first error but if this all boils down to using the Dispatcher, can someone provide an example of how I can use it in my situation to fire off a call to launch the second modal view?
Thanks