Niek Jannink
Niek Jannink

Reputation: 1186

Observing a reactive list and property

I have the following ViewModel

class MyViewModel
{      
    private string _name;

    public MyViewModel()
    {
        CommitChanges = ReactiveCommand.Create(Observable.When(
            this.ObservableForProperty(x => x.Name)
            .And(Childs.CountChanged)
            .Then((one, two) => !string.IsNullOrWhiteSpace(one.Value) && two > 0)));
        CommitChanges.Subscribe(_ => DoCommitChanges());
    }

    public IReactiveList Childs { get ; } = new ReactiveList<object>();

    public string Name
    {
        get { return _name; }
        set { this.RaiseAndSetIfChanged(ref _naam, value); }
    }

    public ReactiveCommand<object> CommitChanges { get; }

    private void DoCommitChanges() { ... }
}

The CanExecute of the CommitChanges command isn't following the observables correctly. For example when I add a child and set the name to something the CanExecute changes to true as expected, but when I then clear the name the CanExecute still stays true. What am I doing wrong?

Upvotes: 0

Views: 1141

Answers (1)

Charles Mager
Charles Mager

Reputation: 26233

When / And / Then, as I understand, will only produce a value when both sequences produce a value. So clearing Name won't produce a value until Childs.Count changes.

There are many ways you can approach this. I'd probably do something like this:

var nameHasValue = this.WhenAny(x => x.Name, x => !string.IsNullOrWhitespace(x.Value));

var isChildsEmpty = Childs.IsEmptyChanged.StartWith(Childs.IsEmpty);

var canCommit = nameHasValue
    .CombineLatest(isChildsEmpty, (hasName, isEmpty) => hasName && !isEmpty);

CommitChanges = ReactiveCommand.Create(canCommit);

Upvotes: 2

Related Questions