2016-07-27 20 views
1

実装ユーザーインターフェイスコマンドにはいくつかの問題があります。 私はwpf、prism、mvvmを使用します。私のアプリはメインとメニューの2つの領域を持っています。 アプリがメニュー項目(NavBarGroup)を登録しているメニュー領域(NavBarControl、Devexpress)に読み込み中です。各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タスクを処理できます。これは何について:AccountListViewModel.LoadUsersCollection()は非同期にすることができるならば、ある

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(); 
    } 
} 

。そうしないと、あなたは、私が間違っている可能性Task.Run

このような
await Task.Run(() => this.AccountListViewModel.LoadUsersCollection()); 
+0

でそれをラップする必要がありますが、それは私のケースからも同様と思われます。 –

+0

違いは、質問では、少なくとも例外的に、火災と忘れのスタイルでタスクを使用することです。しかし、もちろん、同期APIを非同期で呼び出す問題を解決するための明白な方法があるので、これに対するすべてのソリューションは同様に見えます。 'async' /' await'はTPLの 'ContinueWith'の好きなものより流暢に見えますが... – Haukinger

関連する問題