Я использую ReactiveUI
с AvaloniaUI
, и у меня ViewModel с несколькими ReactiveCommands
, а именно: Сканирование, Загрузка и Выполнение.
Сканирование вызывается при обновлении Observable<string>
(когда я получаюштрих-код со сканера).
Загрузка запускается из команды сканирования.
Запуск запускается с помощью кнопки в пользовательском интерфейсе.
Упрощенный код ниже:
var canRun = Events.ToObservableChangeSet().AutoRefresh().ToCollection().Select(x => x.Any());
Run = ReactiveCommand.CreateFromTask<bool>(EventSuite.RunAsync, canRun);
var canLoad = Run.IsExecuting.Select(x => x == false);
var Load = ReactiveCommand.CreateFromTask<string, Unit>(async (barcode) =>
{
//await - go off and load Events.
}, canLoad);
var canReceiveScan = Load.IsExecuting.Select(x => x == false)
.Merge(Run.IsExecuting.Select(x => x == false));
var Scan = ReactiveCommand.CreateFromTask<string, Unit>(async (barcode) =>
{
//do some validation stuff
await Load.Execute(barcode)
}, canReceiveScan);
Barcode
.SubscribeOn(RxApp.TaskpoolScheduler)
.ObserveOn(RxApp.MainThreadScheduler)
.InvokeCommand(Scan);
Каждая команда может быть выполнена только в том случае, если не выполняется никакая другая команда (включая ее). Но я не могу ссылаться на свойство IsExecuting
команды, пока оно не объявлено. Поэтому я пытался объединить наблюдаемые переменные «CanExecute» следующим образом:
canRun = canRun
.Merge(Run.IsExecuting.Select(x => x == false))
.Merge(Load.IsExecuting.Select(x => x == false))
.Merge(Scan.IsExecuting.Select(x => x == false))
.ObserveOn(RxApp.MainThreadScheduler);
// same for canLoad and canScan
Проблема, с которой я столкнулся, заключается в том, что ReactiveCommand продолжит выполняться при выполнении другой команды.
Есть ли лучший / правильный способ реализации этого?