C# 在方法完成之前,如何从ViewModel中的方法更新UI?
我有一个MainWindow.xaml,其中填充了UserControls。我在MainWindow.xaml中有一个控件,它有一个按钮。该按钮绑定到MyViewModel.cs中的以下命令:C# 在方法完成之前,如何从ViewModel中的方法更新UI?,c#,wpf,xaml,user-interface,mvvm,C#,Wpf,Xaml,User Interface,Mvvm,我有一个MainWindow.xaml,其中填充了UserControls。我在MainWindow.xaml中有一个控件,它有一个按钮。该按钮绑定到MyViewModel.cs中的以下命令: public ICommand MyCommand { get { return Get(() => MyCommand, () => new RelayCommand(ExecuteMyCommand, CanExecu
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秒的代码。信使正在向codebehind 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;
}
}
预期结果:按my按钮后,Popup1立即显示并在Method1()执行时停留在窗口中。然后,Popup2替换窗口中的Popup1,并执行Method2()
实际结果:按下“我的”按钮后,UI中什么也没有发生。Method1()和Method2()按预期执行,在它们都运行后(~10秒),将显示Popup2。我从来没见过弹出窗口
我尝试了两种线程/异步方法,但都不起作用。如何让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();
}
不要调用在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 );
}
您在UI线程中执行工作,因此UI线程被您的工作占用,不响应更改和更新自身。您必须在后台线程中执行代码。长时间运行的操作不应在UI线程中执行。使用例如
Task.Run()
。然后,您可以等待任务并根据需要交错UI更新。有关示例,请参见标记的副本。谢谢!我是C#/WPF新手,没有将主线程看作UI线程。我的大多数尝试都是将Messenger发送到另一个线程,但现在很明显,为什么这样做没有意义。一旦我更新了我的代码,我会发布我自己的答案,这样这个问题对某人仍然有用。