2016-07-27 20 views
1

我在实现用户界面命令时遇到了一些困难。 我使用wpf,棱镜和mvvm。我的应用程序有两个区域 - 主菜单和菜单。 当应用程序正在菜单区域(NavBarControl,Devexpress)中注册菜单项(NavBarGroup)时加载。每个NavBarGroup都有一些NavBarItem。当NavBarItem被选中时,绑定正在执行的命令。有些命令允许创建一个实体。但是,该应用程序必须从服务器加载一些数据,并且此时用户界面应该是响应式的。我试图通过下一步的方式达到目的:在wpf&mvvm中使用后台计算实现用户界面命令

this.createAccount.Command = (ICommand)new DelegateCommand(this.ExecuteCreateAccount); 

private void ExecuteCreateAccount() 
    { 
     AppEvent.OnShowNotificationEvent(UTNotificationType.ChangeMainLoaderStatus, "show", null); 
     if (this.isCreateAccountProcessing) 
     { 
      return; 
     } 

     this.isCreateAccountProcessing = true; 
     Task.Factory.StartNew(() => this.AccountListViewModel.LoadUsersCollection()).GetAwaiter().OnCompleted(this.ShowAccountEditor); 
    } 

    private void ShowAccountEditor() 
    { 
     AppEvent.OnShowNotificationEvent(UTNotificationType.ChangeMainLoaderStatus, null, null); 
     this.isCreateAccountProcessing = false; 

     if (this.createAccount.IsSelected) 
     { 
      this.AccountListViewModel.CreateNewItem(); 
     } 
    } 

但也许有更好的方法来丰富这个目标? 当后台计算发生时,应用程序显示加载器(AppEvent.OnShowNotificationEvent)。如果用户选择另一个菜单项,则该命令被视为取消,并且不应显示帐户编辑器。

回答

0

由于您使用的是DevExpress框架,我建议您使用AsyncCommand。根据文档,它为您所描述的场景而设计。

0

棱镜的DelegateCommand可以处理async任务。这个怎么样:

this.createAccount.Command = (ICommand)new DelegateCommand(this.ExecuteCreateAccount); 

private async Task ExecuteCreateAccount() 
{ 
    AppEvent.OnShowNotificationEvent(UTNotificationType.ChangeMainLoaderStatus, "show", null); 
    if (this.isCreateAccountProcessing) 
    { 
     return; 
    } 

    this.isCreateAccountProcessing = true; 
    await this.AccountListViewModel.LoadUsersCollection()); 
    AppEvent.OnShowNotificationEvent(UTNotificationType.ChangeMainLoaderStatus, null, null); 
    this.isCreateAccountProcessing = false; 

    if (this.createAccount.IsSelected) 
    { 
     this.AccountListViewModel.CreateNewItem(); 
    } 
} 

也就是说,如果AccountListViewModel.LoadUsersCollection()可以进行异步。否则,你应该把它包装在这样一个Task.Run

await Task.Run(() => this.AccountListViewModel.LoadUsersCollection()); 
+0

我可能是错的,但它似乎也是从我的情况。 –

+0

区别在于,在这个问题中,您使用的是一种“即忘即忘”式的任务,至少在例外情况下。但是,当然,所有这些解决方案看起来都很相似,因为有一个明显的方法可以解决以异步方式调用同步API的问题。 'async' /'await'看起来比TPL的'ContinueWith'更流利,不过...... – Haukinger