【问题标题】:C# DynamicData and WhenPropertyChanged - skip initial value when collection is initializedC# DynamicData 和 WhenPropertyChanged - 初始化集合时跳过初始值
【发布时间】:2026-02-25 08:45:01
【问题描述】:

我有一个简单的代码:

class ItemViewModel : ReactiveObject
{
    private string _name;
    private string _value;

    public ItemViewModel(string name, string value)
    {
        _name = name;
        _value = value;
    }

    public string Name
    {
        get => _name;
        set => this.RaiseAndSetIfChanged(ref _name, value);
    }

    public string Value
    {
        get => _value;
        set => this.RaiseAndSetIfChanged(ref _value, value);
    }
}

IObservable<IChangeSet<ItemViewModel>> changeSet = CreateChangeSet();

我想对更改集中任何对象中Value 属性的任何更改做出反应,并做一些具有新价值的事情。我试过这样:

changeSet 
    .WhenPropertyChanged(x => x.Value)
    .DistinctUntilChanged()
    .Subscribe(value =>
    {
         // do sth with value
    });

但是WhenPropertyChanged 在初始化集合时为每个项目提供初始值,我想避免这种情况。我该怎么做?

【问题讨论】:

  • 我不确定你想避免什么。是 a) 在一次更改许多项目时多次调用订阅者,还是 b) 订阅者获取初始值而不是更改后的值?
  • 这是我想避免的选项 b)。
  • 你为什么不能这样做?公共字符串值 { 获取 => _value; set => if(value != _value) this.RaiseAndSetIfChanged(ref _value, value);上面的代码告诉你:如果值和上一个不一样,就设置值,否则直接忽略。
  • @Bruno 没关系,另外DistinctUntilChangedif value != value 做同样的工作。我描述的行为来自使用WhenPropertyChanged - 它在集合初始化时提供初始值。我想以某种方式避免它。
  • 有一些方法可以做到这一点,一种是:您可以使用静态字段来检查是否第一次设置了属性(值)(我不推荐),但是,最好了解您为什么要这样做,也许我们可以提供更好的解决方案。

标签: c# dynamic-data reactiveui


【解决方案1】:

您只需将 notifyOnInitialValue 参数设置为 false。默认情况下是真的。我刚刚尝试在沙盒控制台应用程序中进行完整性检查,它确实按预期工作。

changeSet
    .WhenPropertyChanged(x => x.Value, notifyOnInitialValue: false)

来源:https://github.com/reactiveui/DynamicData/blob/63960b0fa7bd0362c40e137498cd0014ba02f3dc/src/DynamicData/Binding/NotifyPropertyChangedEx.cs#L59

【讨论】: