【问题标题】:ReactiveCommand CanExecute reacting to changes in a collectionReactiveCommand CanExecute 对集合中的更改做出反应
【发布时间】:2014-10-31 17:04:51
【问题描述】:

我有一个 ReactiveCollection,里面装满了 Items(也是 ReactiveObjects)。

我想创建一个 ReactiveCommand,仅当集合中的任何项的某些属性设置为 true 时才应启用,例如:

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

因此,只要有一个项目的属性设置为 true,就应该启用该命令。

编辑: 谢谢,保罗。结果代码是这样的:

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)));
}

编辑 2: 我发现了一个陷阱!如果修改这一行:

new ItemViewModel("Engine");

并像这样设置 IsAdded = true

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

…当您运行该按钮时,该按钮在应用程序启动时被禁用,应该启用。似乎在发生某些更改后表达式不会评估。我该如何解决?

编辑 3: 已解决!正如@paul-betts 所说,添加这一行可以解决:

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

上面的代码示例也在更新(在他的回答中也是)。

【问题讨论】:

    标签: mvvm reactive-programming reactiveui


    【解决方案1】:

    这个怎么样

    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));
    

    【讨论】:

    • 我在原帖中添加了一个问题。如果影响 observable 的更改发生在命令创建之前,它最初不会评估。你能复习一下吗?提前致谢!
    • 更新了! StartWith 可以解决其中一些初始状态问题
    猜你喜欢
    • 1970-01-01
    • 2016-08-09
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多