对 ObservableCollection 的更新做出反应

React to updates on ObservableCollection

我有如下一段代码:

ReactiveCommand
    .CreateFromTask(_ => GetPerson())
    .Execute()
    .Subscribe(x => person = x);

var canNext = person?.Friends
                .ToObservableChangeSet()
                .AutoRefresh(x => x.Selected)
                .ToCollection()
                .Select(x => x.Any(y => y.Selected));

MyCommand = ReactiveCommand.CreateFromTask(async _ => Debug.Write("Hello"), canNext);

如何让 canNext 更新以便 disable/enable 我的命令?

如果我用 friendsperson 进行硬编码,则 canNext 在选择和取消选择朋友时工作正常。但是,当将 person 分配给 async 调用 GetPerson() 时,它会破坏任何更新 运行 canNext.

我创建了一个虚拟项目来帮助演示问题。 https://github.com/grierson/updateButton

如何修复?

要获得您想要的行为,您可以先初始化 person,然后当您调用 GetPerson() 时,只需更新您已有的 person,如下所示

person = new Person() { Friends = new ObservableCollection<Friend>() };

ReactiveCommand
    .CreateFromTask(_ => GetPerson())
    .Execute()
    .Subscribe(x =>
    {
        foreach (var friend in x.Friends)
        {
            person.Friends.Add(friend);
        }
    });

var canNext = person?.Friends
    .ToObservableChangeSet()
    .AutoRefresh(x => x.Selected)
    .ToCollection()
    .Select(x => x.Any(y => y.Selected));

MyCommand = ReactiveCommand.CreateFromTask(async _ => Debug.Write("Hello"), canNext);

现在说说你做错了什么:

为什么按钮没有变化?

出现这种行为的原因是当您 运行

ReactiveCommand
    .CreateFromTask(_ => GetPerson())
    .Execute()
    .Subscribe(x => person = x);

var canNext = person?.Friends
    .ToObservableChangeSet()
    .AutoRefresh(x => x.Selected)
    .ToCollection()
    .Select(x => x.Any(y => y.Selected));

MyCommand = ReactiveCommand.CreateFromTask(async _ => Debug.Write("Hello"), canNext);

在您到达设置 MyCommand 的行时,canNext 的值为 null:发生这种情况是因为 personnull那个时间点,因此您将 null 值传递给 CreateFromTaskcanExecute 参数,即您实际上是在设置

MyCommand = ReactiveCommand.CreateFromTask(async _ => Debug.Write("Hello"), null);

或相同之处

MyCommand = ReactiveCommand.CreateFromTask(async _ => Debug.Write("Hello"));

也就是说,您并没有真正将任何信息传递给 canExecuteButton 只是始终处于活动状态,正如您在 运行 上面的代码中看到的那样。

P.S.:感谢您提供简单的示例。这是能够找出问题根源的关键。