#reactiveui #avaloniaui #avalonia
#реактивная команда #avaloniaui #avalonia
Вопрос:
Существует MainViewModel, который имеет свойство ActiveLayoutItem, которое инициализируется только после команды Add (), то есть при инициализации конструктора MainViewModel это свойство будет равно null. В MainViewModel есть команда ReactiveCommandCheck, которая имеет два условия, которые могут быть выполнены:
- ActiveLayoutItem должен быть ненулевым и быть PropertiesViewModel (ActiveLayoutItem — PropertiesViewModel)! = Null;
- (ActiveLayoutItem как PropertiesViewModel) .ReactiveCommand1.CanExecute == true;
Как реализовать эту команду?
public class MainViewModel : ViewModelBase { public ReactiveCommand<Unit, Unit> ReactiveCommandCheck { get; set; } public void RC1Ex() { this.Tools.Clear(); } public ViewModelBase ActiveLayoutItem { get { return _activeLayoutItem; } set => this.RaiseAndSetIfChanged(ref _activeLayoutItem, value); } public MainViewModel() { ReactiveCommandCheck = ReactiveCommand.Create(RC1Ex, ***??? ***); } public void Add() { var vm = new PropertiesViewModel(); ActiveLayoutItem = vm; } } public class PropertiesViewModel : ViewModelBase { public ReactiveCommand<Unit, Unit> ReactiveCommand1 { get; } public void RC1Ex() { Title = ""; } public PropertiesViewModel() { Title = "Documents Properties"; var canEx = this.WhenAnyValue( x => x.Title, x => !string.IsNullOrWhiteSpace(x)); ReactiveCommand1 = ReactiveCommand.Create(RC1Ex, canEx); } }
Ответ №1:
Предположение, что первое условие может быть выражено следующим образом:
var layoutItemIsValid =
this.WhenAnyValue(x => x.ActiveLayoutItem)
.Select(item => item != null amp;amp; item is PropertiesViewModel);
Второе условие может выглядеть примерно так:
var canExecuteChanged =
this.WhenAnyValue(x => x.ActiveLayoutItem)
.OfType<PropertiesViewModel>() // This filters out irrelevant types.
.SelectMany(props => props.ReactiveCommand1.CanExecute);
Тогда нам нужно объединить два условия:
var canDoStuff =
layoutItemIsValid.CombineLatest(
canExecuteChanged,
(valid, canExecute) => valid amp;amp; canExecute);
Это требует тестирования, но я надеюсь, что это поможет хотя бы немного.