如何在方法完成之前从ViewModel中的方法更新UI?

时间:2017-11-08 19:58:58

标签: c# wpf xaml user-interface mvvm

我有一个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();
        }

1 个答案:

答案 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 );
}