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.
Thanks to the answerer. 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));
ClearCommand = ReactiveCommand.Create(shouldRecheck.Select(_ => shouldBeEnabled.Any(x => x)));
}
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?
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));