Я знаю, что есть несколько ответов по этой теме на SO, но я не могу заставить ни одно из решений работать на меня. Я пытаюсь открыть новое окно из команды ICommand, запущенной из таблички данных. Оба следующих события вызывают вышеупомянутую ошибку при создании экземпляра нового окна (в пределах "new MessageWindowP"):
Использование TPL / FromCurrentSynchronizationContext Обновление: работает
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();
}
}
Использование ThreadStart: Обновление: не рекомендуется, см. ответ Джона
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();
}
}
Спасибо
РЕДАКТИРОВАТЬ. Основываясь на полученных ответах, я хотел бы указать, что я также пробовал BeginInvoke в текущем диспетчере, а также выполнял код в исходном методе (так код запускался). См. ниже:
BeginInvoke Обновление: не рекомендуется см. ответ Джона
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();
}
}
В том же потоке Обновление: работает, если вы уже находитесь в потоке пользовательского интерфейса
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, используя ссылку на диспетчер первого / главного окна Обновление: работает
public void Execute(object sender)
{
if (sender is UserC)
{
var user = (UserC)sender;
GeneralManager.MainDispatcher.BeginInvoke(
DispatcherPriority.Normal,
new Action(() => this.CreateMessageWindow(user)));
}
}
где GeneralManager.MainDispatcher - ссылка на Диспетчер первого создаваемого мной окна:
[somewhere far far away]
mainP = new MainP();
MainDispatcher = mainP.View.Dispatcher;
Я в растерянности.
BeginInvoke
? В каком потоке работает вашExecute
? - person Vlad   schedule 26.04.2012Dispatcher.CurrentDispatcher
, как здесь. Смотрите обновление моего ответа. - person Jon   schedule 26.04.2012