MVVM模式、WPF、BackgroundWorker与UI更新

4
我正在学习使用WPF的MVVM模式,尝试创建一个用于加载应用程序的简单启动画面。 我有一个名为Loading的简单类,其中包含两个属性,这些属性已经与我的接口绑定。
public class Loading : INotifyPropertyChanged
{
    /// <summary>
    ///     Define current status value from 0 to 100.
    /// </summary>
    private int _currentStatus;

    /// <summary>
    ///     Define current status text.
    /// </summary>
    private string _textStatus;

    /// <summary>
    ///     Define constructor.
    /// </summary>
    public Loading(int status, string statusText)
    {
        _currentStatus = status;
        _textStatus = statusText;
    }

    public int CurrentStatus
    {
        get { return _currentStatus; }
        set
        {
            _currentStatus = value;
            OnPropertyChanged("CurrentStatus");
        }
    }

    public string TextStatus
    {
        get { return _textStatus; }

        set
        {
            _textStatus = value;
            OnPropertyChanged("TextStatus");
        }
    }

    #region Interfaces

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

从我的ctor ViewModel中我实例化了这个模型

Loading = new Loading(0, "Loading...");

并且运行一个新线程,调用函数GetSystemInfo()执行一些操作,以加载一些信息。

Thread systemInfo = new Thread(GetSystemInfo);
systemInfo.IsBackground = true;
systemInfo.Start();

我正在使用GetSystemInfo()更新用户界面:
Loading.TextStatus = "Loading User Information...";
Loading.CurrentStatus = 50;

目前为止情况良好。线程正在正确地更新用户界面,但问题在于我希望在加载完成后关闭此闪屏并打开一个新窗口,但是我无法检查线程是否已完成,或者至少我没有找到一种方法来做到这一点。

有什么办法可以解决这个问题吗?

谢谢。

1个回答

3
你可以通过使用Task类(通过任务并行库)与异步等待的组合轻松实现此操作。
当你在一个 Task 上使用 await 时,控制权将被返回给调用者。在您的情况下,调用者来自 UI 线程,因此控件将返回到 UI 消息循环,保持应用程序响应。一旦线程完成工作,它将返回到await之后的下一行,然后您就可以打开闪屏窗口。
代码示例如下:
public async void MyEventHandler(object sender, EventArgs e)
{
    await Task.Run(() => GetSystemInfo());
    // Here, you're back on the UI thread. 
    // You can open a splash screen.
}

非常感谢,我花了很多时间尝试解决这个问题,而解决方案却非常简单 :D - Babalaus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接