我有一个MainWindow.xaml,用UserControls填充。我在MainWindow.xaml中有一个带按钮的控件。该按钮绑定到MyViewModel.cs中的以下命令:
public ICommand MyCommand
{
get
{
return Get(() => MyCommand, () => new RelayCommand(ExecuteMyCommand, CanExecuteMyCommand));
}
}
public void ExecuteMyCommand()
{
Messenger.Default.Send(new NotificationMessage(this, MainWindowMessageBus.ShowPopup1), MainWindowMessageBus.Token);
Method1();
Messenger.Default.Send(new NotificationMessage(this, MainWindowMessageBus.ShowPopup2), MainWindowMessageBus.Token);
Method2();
}
public bool CanExecuteInsertBedCommand()
{
return true;
}
Method1()和Method2()执行每个大约需要5秒的代码。信使正在向MainWindow.xaml.cs代码发送消息:
Popup1 popup1;
Popup2 popup2;
private void NotificationMessageReceived(NotificationMessage msg)
{
switch(msg.Notification)
{
case MainWindowMessageBus.ShowPopup1:
popup1 = new Popup1();
ControlContainer.Children.Add(popup1);
break;
case MainWindowMessageBus.ShowPopup2:
// Remove popup1
ControlContainer.Children.Remove(popup1);
popup1 = null;
// Add popup2
popup2 = new Popup2();
ControlContainer.Children.Add(popup2);
break;
default:
break;
}
}
预期结果:按下我的按钮后,Popup1立即显示并在Method1()执行时停留在窗口中。然后,Popup2替换窗口中的Popup1,并执行Method2()。
实际结果:按下我的按钮后,UI中没有任何反应。 Method1()和Method2()按预期执行,在它们都运行(~10秒)后,显示Popup2。我从未见过Popup1。
我尝试了几种线程/异步方法,但它们没有用。如何让ExecuteMyCommand()更新UI?
修改
好的,所以我出于某种原因无法回答我自己的问题。我不认为这个问题是指定线程的重复,因为这意味着我已经知道我需要在后台运行Method1(),我没有。无论如何,这是我改变的:
public async void ExecuteMyCommand()
{
Messenger.Default.Send(new NotificationMessage(this, MainWindowMessageBus.ShowPopup1), MainWindowMessageBus.Token);
await Task.Run(() =>
{
Method1();
});
Messenger.Default.Send(new NotificationMessage(this, MainWindowMessageBus.ShowPopup2), MainWindowMessageBus.Token);
Method2();
}
答案 0 :(得分:-1)
不要调用在UI线程中花费几次的方法。
您可以尝试创建自定义窗口。 在此,您可以显示您的用户的所有自定义信息。 由于您的方法需要多次,因此您可以添加取消按钮作为示例。 您还可以添加进度条。当一种方法需要时间时,了解系统的状态是很好的。
按下按钮时试试这个 - >调用命令午餐线程
在你的命令中:
void Command()`
{
// run a thread, create a window and show it
// you can declare the thread outside if you want use something like join
Thread threadExecute = new Thread(Execute);
w = new WinTest();
w.Topmost = true;
w.Show();
threadExecute.Start();
}
// Call when your thread terminated
void finish()
{
w.Close();
}
void Execute()
{
// Your big method 1
// Change the window information
// big method 2
this.Dispatcher.Invoke( finish );
}