ожидайте Command.Execute с или без асинхронного действия - PullRequest
0 голосов
/ 27 февраля 2019

Я наткнулся на странный случай, и я застрял на нем.

У меня есть 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, и завершение его с помощью задачи ничего не решит ...

По сути, у меня есть асинхронный метод, который не знает, что это асинхронный метод.

1 Ответ

0 голосов
/ 27 февраля 2019

Вам понадобится некоторая концепция асинхронной команды .Некоторые библиотеки MVVM имеют это встроенное в эти дни:

public interface IAsyncCommand : ICommand
{
  Task ExecuteAsync(object parameter);
}

, где реализация ICommand.Execute всегда async void ICommand.Execute(object parameter) => await ExecuteAsync(parameter).Затем вы можете определить свой собственный AsyncCommand, который работает точно так же, как Command, за исключением того, что он реализует IAsyncCommand.

Затем ваши модели представлений выставят IAsyncCommand вместо ICommand, и ваша всплывающая логика может использоватьчто:

private async void OnMainActionCommand(object obj)
{
  MainActionCommand.CanExecute(false);
  await _mainActionCommandToRun.ExecuteAsync(null);
  MainActionCommand.CanExecute(true);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...