I know that there are several answers to this topic about SO, but I cannot get any of the solutions working for me. I am trying to open a new window from ICommand released from a dataset. Both of these parameters give the above error when creating a new window (in the "new MessageWindowP"):
Using TPL / FromCurrentSynchronizationContext Update: Works
public class ChatUserCommand : ICommand { public void Execute(object sender) { if (sender is UserC) { var user = (UserC)sender; var scheduler = TaskScheduler.FromCurrentSynchronizationContext(); Task.Factory.StartNew(new Action<object>(CreateMessageWindow), user,CancellationToken.None, TaskCreationOptions.None,scheduler); } } private void CreateMessageWindow(object o) { var user = (UserC)o; var messageP = new MessageWindowP(); messageP.ViewModel.Participants.Add(user); messageP.View.Show(); } }
Using ThreadStart: Update: not recommended, see Jon's answer
public class ChatUserCommand : ICommand { public void Execute(object sender) { if (sender is UserC) { var user = (UserC)sender; var t = new ParameterizedThreadStart(CreateMessageWindow); var thread = new Thread(t); thread.SetApartmentState(ApartmentState.STA); thread.Start(sender); } } private void CreateMessageWindow(object o) { var user = (UserC)o; var messageP = new MessageWindowP(); messageP.ViewModel.Participants.Add(user); messageP.View.Show(); } }
thank
EDIT. Based on the answers so far, I would like to point out that I also tried BeginInvoke in the current dispatcher, and also executed the code in the original method (how the code started). See below:
BeginInvoke Update: It is not recommended to see Jon's answer
public class ChatUserCommand : ICommand { public void Execute(object sender) { if (sender is UserC) { var user = (UserC)sender; Dispatcher.CurrentDispatcher.BeginInvoke(new Action<object>(CreateMessageWindow), sender); } } private void CreateMessageWindow(object o) { var user = (UserC)o; var messageP = new MessageWindowP(); messageP.ViewModel.Participants.Add(user); messageP.View.Show(); } }
In the same thread Update: works if you are already in the user interface thread
public class ChatUserCommand : ICommand { public void Execute(object sender) { if (sender is UserC) { var user = (UserC)sender; var messageP = new MessageWindowP(); messageP.ViewModel.Participants.Add(user); messageP.View.Show(); } } }
BeginInvoke using the link to the first / main window manager . Update: Works
public void Execute(object sender) { if (sender is UserC) { var user = (UserC)sender; GeneralManager.MainDispatcher.BeginInvoke( DispatcherPriority.Normal, new Action(() => this.CreateMessageWindow(user))); } }
where GeneralManager.MainDispatcher is a link to the First Window Dispatcher that I create:
[somewhere far far away] mainP = new MainP(); MainDispatcher = mainP.View.Dispatcher;
I'm at a loss.