C# 订阅ObservableCollection项属性已更改-WPF

C# 订阅ObservableCollection项属性已更改-WPF,c#,.net,system.reactive,C#,.net,System.reactive,我需要订阅列表中某个对象的属性。我发现这个例子()非常好用,但是如果我在列表中添加一个新元素,它就不起作用了。有解决办法吗?谢谢大家! 编辑 IDisposable subscription = Observable .FromEventPattern <NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>( x =&

我需要订阅列表中某个对象的属性。我发现这个例子()非常好用,但是如果我在列表中添加一个新元素,它就不起作用了。有解决办法吗?谢谢大家!

编辑

IDisposable subscription =
    Observable
        .FromEventPattern
            <NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
                x => MyList.CollectionChanged += x,
                x => MyList.CollectionChanged -= x)
        .Where(x => x.EventArgs.Action == NotifyCollectionChangedAction.Add)
        .SelectMany(x => x.EventArgs.NewItems.Cast<MyCustomClass>())
        .SelectMany(x =>
        {
            CallMethodWhenAddItem(x);
            return x.OnPropertyChange(nameof(x.MyCustomProperty));
        })
        .Subscribe(x =>
            // x is PropertyChangedEventArgs, not MyCustomClass
            if (x.MyCustomProperty == "SomeValue") {
                RunAction();
            }
        });


public static IObservable<PropertyChangedEventArgs> OnPropertyChange<T>(this T currentSource, string propertyName)
    where T : INotifyPropertyChanged
{
    return
        Observable
            .FromEventPattern
                <PropertyChangedEventHandler, PropertyChangedEventArgs>(
                    eventHandler => eventHandler.Invoke,
                    x => currentSource.PropertyChanged += x,
                    x => currentSource.PropertyChanged -= x)
            .Where(x => x.EventArgs.PropertyName == propertyName)
            .Select(x => x.EventArgs);
}
IDisposable订阅=
可观察
.FromEventPattern
(
x=>MyList.CollectionChanged+=x,
x=>MyList.CollectionChanged-=x)
.Where(x=>x.EventArgs.Action==NotifyCollectionChangedAction.Add)
.SelectMany(x=>x.EventArgs.NewItems.Cast())
.SelectMany(x=>
{
CallMethodWhenAddItem(x);
返回x.OnPropertyChange(name of(x.MyCustomProperty));
})
.订阅(x=>
//x是PropertyChangedEventArgs,而不是MyCustomClass
如果(x.MyCustomProperty==“SomeValue”){
RunAction();
}
});
公共静态IObservable OnPropertyChange(此T currentSource,字符串propertyName)
其中T:INotifyPropertyChanged
{
返回
可观察
.FromEventPattern
(
eventHandler=>eventHandler.Invoke,
x=>currentSource.PropertyChanged+=x,
x=>currentSource.PropertyChanged-=x)
.Where(x=>x.EventArgs.PropertyName==PropertyName)
.Select(x=>x.EventArgs);
}
你能用以下问题给我一点指导吗

1) 使用“eventHandler=>eventHandler.Invoke”和不使用它有什么区别。互联网上的许多例子都使用它,而其他的则不使用。我真的看不出有什么区别

2) 如何从“动态”添加的属性取消订阅。把它从列表中删除

谢谢

使用
System.Func
参数将给定的事件处理程序转换为与基础.NET事件兼容的委托。如果不需要,不要使用它。它实际上用于连接非标准事件处理程序

您不应该进行嵌套订阅。这样,您就不必担心如何处理内部订阅。按如下方式编写查询:

IDisposable subscription =
    Observable
        .FromEventPattern
            <NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
                x => MyList.CollectionChanged += x,
                x => MyList.CollectionChanged -= x)
        .Where(x => x.EventArgs.Action == NotifyCollectionChangedAction.Add)
        .SelectMany(x => x.EventArgs.NewItems.Cast<MyCustomClass>())
        .SelectMany(x =>
        {
            CallMethodWhenAddItem(x);
            return x.OnPropertyChange(nameof(x.MyCustomProperty));
        })
        .Subscribe(_ => { });
IDisposable订阅=
可观察
.FromEventPattern
(
x=>MyList.CollectionChanged+=x,
x=>MyList.CollectionChanged-=x)
.Where(x=>x.EventArgs.Action==NotifyCollectionChangedAction.Add)
.SelectMany(x=>x.EventArgs.NewItems.Cast())
.SelectMany(x=>
{
CallMethodWhenAddItem(x);
返回x.OnPropertyChange(name of(x.MyCustomProperty));
})
.Subscribe(=>{});

根据评论更新:

void Main()
{
    var MyList = new ObservableCollection<int>();

    IDisposable subscription =
        Observable
            .FromEventPattern
                <NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
                    x => MyList.CollectionChanged += x,
                    x => MyList.CollectionChanged -= x)
            .Where(x => x.EventArgs.Action == NotifyCollectionChangedAction.Add)
            .SelectMany(x => x.EventArgs.NewItems.Cast<MyCustomClass>())
            .SelectMany(x =>
            {
                CallMethodWhenAddItem(x);
                return x.OnPropertyChange(nameof(x.MyCustomProperty));
            })
            .Where(x => x.MyCustomProperty == "SomeValue")
            .Subscribe(_ => { });
}

public static class Ex
{
    public static IObservable<T> OnPropertyChange<T>(this T currentSource, string propertyName)
        where T : INotifyPropertyChanged
    {
        return
            Observable
                .FromEventPattern
                    <PropertyChangedEventHandler, PropertyChangedEventArgs>(
                        eventHandler => eventHandler.Invoke,
                        x => currentSource.PropertyChanged += x,
                        x => currentSource.PropertyChanged -= x)
                .Where(x => x.EventArgs.PropertyName == propertyName)
                .Select(x => currentSource);
    }
}

public class MyCustomClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public string  MyCustomProperty { get; set; }
}

public void CallMethodWhenAddItem(MyCustomClass x) { }
void Main()
{
var MyList=新的ObservableCollection();
IDisposable订阅=
可观察
.FromEventPattern
(
x=>MyList.CollectionChanged+=x,
x=>MyList.CollectionChanged-=x)
.Where(x=>x.EventArgs.Action==NotifyCollectionChangedAction.Add)
.SelectMany(x=>x.EventArgs.NewItems.Cast())
.SelectMany(x=>
{
CallMethodWhenAddItem(x);
返回x.OnPropertyChange(name of(x.MyCustomProperty));
})
.Where(x=>x.MyCustomProperty==“SomeValue”)
.Subscribe(=>{});
}
公共静态类
{
公共静态IObservable OnPropertyChange(此T currentSource,字符串propertyName)
其中T:INotifyPropertyChanged
{
返回
可观察
.FromEventPattern
(
eventHandler=>eventHandler.Invoke,
x=>currentSource.PropertyChanged+=x,
x=>currentSource.PropertyChanged-=x)
.Where(x=>x.EventArgs.PropertyName==PropertyName)
.选择(x=>currentSource);
}
}
公共类MyCustomClass:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
公共字符串MyCustomProperty{get;set;}
}
public void callMethodWhenadItem(MyCustomClass x){}

谢谢您的帮助。我有一个关于这个实现的问题。在我写的示例中,缺少了一些我认为不相关的东西。当一个元素被添加到集合中时,我会调用一个方法(我修改了这个示例)。这种改变的正确实施方式是什么?谢谢大家!@avechuche-它与您现有的代码没有太大区别。我已经更新了我的答案。@avechuche-除了启动可观察对象之外,做
.Subscribe(=>{})
还有什么意义?i、 扔掉价值?我发现了你认为的问题。在订阅中,我需要访问更改属性的对象。我最初实现中的变量X是完整的对象(MyCustomClass)。在本例中,订阅变量的类型为“PropertyChangedEventArgs”。为了更好地理解,我编辑了这个例子。我想我试图修改他的答案,而不是我的例子。没有注意:)