简体   繁体   English

INotifyPropertyChanged通过Linq引用它的更新属性

[英]INotifyPropertyChanged updating properties that refer to it via Linq

I have a collection of classes contained in a ObservibaleCollection<MyObj> and MyObj implements INotifyPropertyChanged , but I need a property located outside of it that references a property in the collection via linq and creates its own collection to update on both the collection change and any of its content linq bound properties changing. 我有一个ObservibaleCollection<MyObj>包含的类的集合,并且MyObj实现了INotifyPropertyChanged ,但是我需要一个位于其外部的属性,该属性通过linq引用集合中的一个属性,并创建自己的集合以同时更新集合更改和任何它的内容linq绑定属性发生了变化。

For sake of argument and simplicity lets say my class MyObj contains a property called IsVisible . 为了论证和简化起见,假设我的类MyObj包含一个名为IsVisible的属性。 I want a property that implements its own INotifyPropertyChanged to get a list of MyObj where IsVisible == true and keep it up to date regardless id the collection of MyObj changes or the IsVisible property does. 我想要一个实现自己的INotifyPropertyChanged的属性,以获取MyObj的列表,其中IsVisible == true,无论MyObj的集合的ID更改或IsVisible属性执行任何操作,都应使其保持最新。

Is this possible without attaching to the collection changed event and subsequently just directly attaching to each child MyObj.IsVisible property? 是否可以在不附加到集合更改事件的情况下,然后仅直接附加到每个子MyObj.IsVisible属性,这是否可能? Is there a way to get INotify to bubble up through linq? 有没有办法让INotify通过linq冒泡?

public class MyObj:INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public bool IsVisible
    {
        get { return _IsVisible; }
        protected set { if (value != _IsVisible) { _IsVisible= value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsVisible")); } }
    }
    private bool _IsVisible;
}

public class Foo
{
    ObservableCollection<MyObj> myObjs = new ObservableCollection<MyObj>();
    ObservableCollection<MyObj> myVisibleObjs {
        get{
            return myObjs.where(o => o.IsVisible);
        }
    }
}

I hope what I'm asking makes sense. 我希望我的要求是有道理的。

You could make use of Reactive Extensions, but for this specific requirement - maintaining a myVisibleObjs - I would use the dynamic data lib. 您可以使用Reactive Extensions,但是对于此特定要求-维护myVisibleObjs-我将使用动态数据库

Try out the following: 尝试以下方法:

    static void Main(string[] args)
    {
        Foo f = new Foo();

        f.BindToVisibleObjects();

        // add more dummy data
        f.Add(false);
        f.Add(true);

        // There will be 2 visible objects in MyVisibleObjects
        foreach (var d in f.MyVisibleObjects)
        {
            Console.WriteLine(d.IsVisible);
        }
        Console.ReadKey();
    }

    public class Foo
    {
        ObservableCollection<MyObj> myObjs = new ObservableCollection<MyObj>();
        public ReadOnlyObservableCollection<MyObj> MyVisibleObjects;

        public Foo()
        {
            // add some dummy data
            myObjs.Add(new MyObj() { IsVisible = true });
            myObjs.Add(new MyObj() { IsVisible = false });
        }

        public void BindToVisibleObjects()
        {
            myObjs.ToObservableChangeSet()
                .Filter(o => o.IsVisible)
                .Bind(out MyVisibleObjects)
                .DisposeMany()
                .Subscribe();
        }

        public void Add(bool vis)
        {
            myObjs.Add(new MyObj() { IsVisible = vis });
        }
    }

The key here is that we bind the filtered observable changeset to a new collection that will be updated as your myObjs changes. 这里的关键是我们将过滤后的可观察变更集绑定到一个新集合,该集合将随着myObjs的变更而更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM