我一直在尝试为WPF应用程序编写MVVM屏幕,使用async和await关键字编写异步方法来实现以下三个方面:1. 初始加载数据,2. 刷新数据,3. 保存更改并刷新。虽然我已经实现了这些,但是代码非常混乱,我认为肯定有更好的实现方式。有人能够提供简单的实现建议吗?
以下是我的ViewModel的缩减版本:
以下是我的ViewModel的缩减版本:
public class ScenariosViewModel : BindableBase
{
public ScenariosViewModel()
{
SaveCommand = new DelegateCommand(async () => await SaveAsync());
RefreshCommand = new DelegateCommand(async () => await LoadDataAsync());
}
public async Task LoadDataAsync()
{
IsLoading = true; //synchronously set the busy indicator flag
await Task.Run(() => Scenarios = _service.AllScenarios())
.ContinueWith(t =>
{
IsLoading = false;
if (t.Exception != null)
{
throw t.Exception; //Allow exception to be caught on Application_UnhandledException
}
});
}
public ICommand SaveCommand { get; set; }
private async Task SaveAsync()
{
IsLoading = true; //synchronously set the busy indicator flag
await Task.Run(() =>
{
_service.Save(_selectedScenario);
LoadDataAsync(); // here we get compiler warnings because not called with await
}).ContinueWith(t =>
{
if (t.Exception != null)
{
throw t.Exception;
}
});
}
}
在视图中,IsLoading被公开绑定到了一个繁忙指示器。
当屏幕第一次被浏览时或者刷新按钮被按下时,导航框架会调用LoadDataAsync方法。这个方法应该同步设置IsLoading,然后将控制权返回给UI线程,直到服务返回数据。最后抛出任何异常,以便全局异常处理程序捕获(不接受讨论!)。
SaveAync由按钮调用,传递表单中的更新值给服务。它应该同步设置IsLoading,异步调用服务上的Save方法,然后触发刷新。