订阅ObservableCollection项属性已更改 - WPF

问题描述 投票:3回答:1

我需要订阅列表中对象的属性。我找到了这个例子(https://stackoverflow.com/a/18770397/3954928),它工作得很完美,但是如果我在列表中添加一个新元素,它就不起作用了。有解决方案吗谢谢!

编辑

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

你可以用以下问题引导我一点吗?

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

2)我如何取消订阅“动态”添加的属性。只需将其从列表中删除?

谢谢!

c# .net system.reactive
1个回答
1
投票

System.Func<EventHandler<TEventArgs>, TDelegate>参数用于将给定的事件处理程序转换为与底层.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(_ => { });

根据评论更新:

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) { }
© www.soinside.com 2019 - 2024. All rights reserved.