我碰到一个奇怪的案件,被卡在上面。
我有一个Popup View + ViewModel,它是其中的一个按钮。弹出窗口从其他视图获取命令以执行按钮。
现在,我想在单击按钮后立即禁用它,运行命令然后将其禁用。
这就是我现在拥有的:
PopupViewModel
public override Task InitializeAsync(object navigationData)
{
PopupModel model = (PopupModel) navigationData;
...
_mainActionCommandToRun = model.MainActionCommand;
...
return base.InitializeAsync(navigationData);
}
private void OnMainActionCommand(object obj)
{
MainActionCommand.CanExecute(false);
_mainActionCommandToRun.Execute(null);
MainActionCommand.CanExecute(true);
}
一些查看如何使用弹出窗口
await DialogService.ShowPopupAsync<PopupViewModel>(new PopupModel
{
...
MainActionCommand = new Command(
() =>
{
DoSomeThing();
})
});
这种情况下就像魅力。当分配给命令的动作为异步时,它将变得复杂。
某些具有异步操作的视图
await DialogService.ShowPopupAsync<PopupViewModel>(new PopupModel
{
...
MainActionCommand = new Command(
async () =>
{
await DoSomeThing();
})
});
在这种情况下,_mainActionCommandToRun.Execute(null)将触发异步操作并继续执行CanExecute(true)。
我无法等待Execute,因为它是一个void方法,用任务包装它不会解决任何问题...
基本上,我有一个不知道它是异步方法的异步方法。
答案 0 :(得分:0)
您将需要一些asynchronous command的概念。如今,某些MVVM库具有内置功能:
std::unique
其中public interface IAsyncCommand : ICommand
{
Task ExecuteAsync(object parameter);
}
实现始终为ICommand.Execute
。然后,您可以定义自己的async void ICommand.Execute(object parameter) => await ExecuteAsync(parameter)
,其作用类似于AsyncCommand
,但它实现了Command
。
然后让您的视图模型公开IAsyncCommand
而不是IAsyncCommand
,并且您的弹出逻辑可以使用它:
ICommand