ReactiveCommand CanExecute reacting to changes in a collection

本小妞迷上赌 提交于 2019-12-25 04:45:23

问题


I have a ReactiveCollection filled with Items (that are ReactiveObjects as well).

I want to create a ReactiveCommand that should be enabled only when any of the items in the collection has some property set to true, something like:

MyCommand = ReactiveCommand.Create( watch items in collection to see if item.MyProp == true ) 

So anytime there is one of the items with the property set to true, the command should be enabled.

EDIT: Thanks, Paul. The resulting code is this:

public MainViewModel()
{
    Items = new ReactiveList<ItemViewModel>
                {
                    new ItemViewModel("Engine"),
                    new ItemViewModel("Turbine"),
                    new ItemViewModel("Landing gear"),
                    new ItemViewModel("Wings"),
                };

    Items.ChangeTrackingEnabled = true;

    var shouldBeEnabled = Items.CreateDerivedCollection(x => x.IsAdded);

    var shouldRecheck = Observable.Merge(
        // When items are added / removed / whatever
        shouldBeEnabled.Changed.Select(_ => Unit.Default),
        // When any of the bools in the coll change
        shouldBeEnabled.ItemChanged.Select(_ => Unit.Default));

    // Kick off a check on startup
    shouldRecheck = shouldRecheck.StartWith(Unit.Default);

    ClearCommand = ReactiveCommand.Create(shouldRecheck.Select(_ => shouldBeEnabled.Any(x => x)));
}

EDIT 2: I've discovered a trap! If you modify this line:

new ItemViewModel("Engine");

and set the IsAdded = true like this

new ItemViewModel("Engine") { IsAdded = true };

… when you run the button is disabled when the application starts and it should be enabled. It seems like the expression doesn't evaluate after some change occurs. How can I solve it?

EDIT 3: Solved! As @paul-betts says, it can be solved adding this line:

// Kick off a check on startup
shouldRecheck = shouldRecheck.StartWith(Unit.Default);

The code sample is also update above (and in his answer, too).


回答1:


How about this

mySourceCollection.ChangeTrackingEnabled = true;
shouldBeEnabled = mySourceCollection.CreateDerivedCollection(x => x.MyProp);

var shouldRecheck = Observable.Merge(
    // When items are added / removed / whatever
    shouldBeEnabled.Changed.Select(_ => Unit.Default),

    // When any of the bools in the coll change
    shouldBeEnabled.ItemChanged.Select(_ => Unit.Default));

// Kick off a check on startup
shouldRecheck = shouldRecheck.StartWith(Unit.Default);

myCmd = ReactiveCommand.Create(shouldRecheck.Select(_ => shouldBeEnabled.All(x => x));


来源:https://stackoverflow.com/questions/26679926/reactivecommand-canexecute-reacting-to-changes-in-a-collection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!