Просто установка IsBusy не работает, потому что команда не получает уведомления при изменении IsBusy, как и пользовательский интерфейс. Вы должны использовать RaiseCanExecuteChanged, чтобы уведомить всех. Лучше всего просто использовать ObservedCanExecute после создания DelegateCommand (Fluent API, но обратите внимание, что можно наблюдать только одно свойство). Он позаботится об этом за вас и автоматически вызовет RaiseCanExecuteChanged.
Вот пример, как я обычно справляюсь с этим:
public MyViewModel(): ViewModelBase
{
private readonly INavigationService _navigationService;
public bool IsBusy { get; set; }
public ICommand ShowEventDetailsCommand { get; private set; }
public MyViewModel(INavigationService navService)
{
_navigationService = navService;
ShowEventDetailsCommand = new DelegateCommand<string>(async(obj) => await ExecuteShowEventDetailsCommand(obj)).ObservesCanExecute(() => !IsBusy);
}
public async Task ExecuteShowEventDetailsCommand(obj)
{
IsBusy = true; // Note this is not thread safe, just for demonstration
try
{
await _navigationService.NavigateAsync(...);
}
finally
{
IsBusy = false;
}
}
}
Обычно я так поступаю. Но обратите внимание, что доступ на IsBusy не является потокобезопасным, поэтому вы должны использовать что-то, что есть. У меня есть что-то вроде LockActivityHandler с .TryLock, .Unlock и .IsLocked.
if(LockActivityHandler.TryLock())
{
try
{
//DoStuff
}
finally
{
LockActivityHandler.Unlock();
}
}
IsLocked можно привязать к свойству Enabled элементов пользовательского интерфейса, чтобы отключить их. Даже если они не отключены и выполняется другое действие, новое действие не будет выполнено из-за TryLock () => false
PS: Это также записано в документации с большим количеством примеров, поэтому вы можете посмотреть здесь: https://prismlibrary.github.io/docs/commanding.html