从WPF中的ViewModel类(MVVM模式)更新UI

Tho*_*ock 9 wpf mvvm

我在我的第一个WPF应用程序中使用MVVM模式,并且遇到了我认为非常基本的问题.

当用户点击我视图上的"保存"按钮时,会执行一个命令,该命令在我的ViewModel中调用私有void Save().

问题是"Save()"中的代码需要一些时间来执行,所以我想在执行大块代码之前隐藏UI视图中的"保存"按钮.

问题是视图不会更新,直到所有代码都在viewmodel中执行.在执行Save()代码之前,如何强制视图重绘并处理PropertyChanged事件?

另外,我想要一种可重复使用的方式,这样我也可以轻松地在其他页面中做同样的事情.其他人已经做过这样的事了吗?一个"正在加载......"的消息?

Hei*_*nzi 11

如果需要很长时间,请考虑使用单独的线程,例如使用a BackgroundWorker,以便UI线程可以在执行操作时保持响应(即更新UI).

在你的Save方法中,你会的

  • 更改UI(即修改IsBusySaving绑定到UI的一些INotifyPropertyChanged或DependencyProperty 布尔值,隐藏"保存"按钮并显示一些进度条IsIndeterminate = True)和
  • 开始一个BackgroundWorker.

DoWorkBackgroundWorker 的事件处理程序中,您执行冗长的保存操作.

RunWorkerCompletedUI线程中执行的事件处理程序中,您设置IsBusySaving为false并可能更改UI中的其他内容以显示您已完成.

代码示例(未经测试):

BackgroundWorker bwSave;
DependencyProperty IsBusySavingProperty = ...;

private MyViewModel() {
    bwSave = new BackgroundWorker();

    bwSave.DoWork += (sender, args) => {
        // do your lengthy save stuff here -- this happens in a separate thread
    }

    bwSave.RunWorkerCompleted += (sender, args) => {
        IsBusySaving = false;
        if (args.Error != null)  // if an exception occurred during DoWork,
            MessageBox.Show(args.Error.ToString());  // do your error handling here
    }
}

private void Save() {
    if (IsBusySaving) {
        throw new Exception("Save in progress -- this should be prevented by the UI");
    }
    IsBusySaving = true;
    bwSave.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)