在 wpf 和 mvvm 中使用后台计算实现用户界面命令



我在实现用户界面命令方面遇到了一些困难。我使用wpf、prism和mvvm。我的应用程序有两个区域-主菜单和菜单。当应用程序在菜单区域(NavBarControl,Devexpress)加载时,注册菜单项(NavBarGroup)。每个NavBarGroup都有一些NavBarItem。选择NavBarItem时,绑定的命令将执行。某些命令允许创建实体。但对于该应用程序,必须从服务器加载一些数据,在这个时候,用户交互控制应该是有响应的。我试图通过下一种方式达到这种用途:

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)。如果用户选择另一个菜单项,则该命令被视为已取消,并且不应显示帐户编辑器。

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

Prism的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() );

最新更新