【问题标题】:CanExecute depending on two lists using ReactiveUICanExecute 取决于使用 ReactiveUI 的两个列表
【发布时间】:2015-12-16 12:23:36
【问题描述】:

在我的应用中,我有一个带有两个列表的 ViewModel。还有一个动作是 CanExecute 属性依赖于两个列表状态。我正在使用 ReactiveUI。到目前为止,我得到了以下(工作)实现:

public ReactiveList<Defect> Defects { get; } = new ReactiveList<Defect>();
public ReactiveList<State> States { get; } = new ReactiveList<State>();

public ReactiveCommand<object> Print { get; }

// this stream is artificial it is only needed to get notifications from both above
private IObservable<bool> SelectingStream { get; }

ctor()
{
    Defects.ChangeTrackingEnabled = true;
    States.ChangeTrackingEnabled = true;

    SelectingStream = States.ItemChanged.CombineLatest(Defects.ItemChanged, (a, b) =>
    {
        // here is the condition that needs to be met in order to can execute action
        return States.Count(s => s.IsSelected) == 1 &&
               Defects.Any(d => d.IsActive);
    });

    Print = ReactiveCommand.Create(
        this.WhenAnyObservable(x => x.SelectingStream)
    );
}

它确实有效,但我认为这种方法更像是解决方法。可以吗?有更直接的解决方案吗?

【问题讨论】:

    标签: c# mvvm reactiveui


    【解决方案1】:

    由于您可能需要监听/响应内部对象的变化,ItemChanged 可能是它可以得到的最简单的方法(尽管相当繁重)。

    虽然有一些评论:

    • 您可以避免 observable 属性和 whenAnyObservable 调用,只需编写 Print = ReactiveCommand.Create(selectingStream)

    • 请注意,ItemChanged 不会在您向列表中添加/删除元素时触发,因此您的可观察条件也应该与列表 Changed 流合并以涵盖这一点

    • 您应该将CombineLatest 替换为Merge 以避免泄漏对象(您实际上不需要存储每个流的最新状态,不使用a/b)。

    • 当您依赖的属性以外的属性发生更改时,您可以避免触发检查

    最终结果应该是这样的:

    new [] {
        States.Changed.SelectUnit(),
        States.ItemChanged.Where(ea => ea.PropertyName == "IsSelected").SelectUnit(),
        Defects.Changed.SelectUnit(),
        Defects.ItemChanged.Where(ea => ea.PropertyName == "IsActive").SelectUnit() }
    .Merge()
    .Select(_ => States.Count(s => s.IsSelected) == 1 && Defects.Any(d => d.IsActive))
    

    (使用方便的SelectUnit() 扩展方法)

    不是很简单,是吗? :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多