EntityFramework EntityCollection Observing CollectionChanged

房东的猫 提交于 2019-12-07 04:03:47

问题


I'm using EntityFramework database first in an application. I would like somehow to be notified of changes to an EntityCollection in my ViewModel. It doesn't directly support INotifyCollectionChanged (why?) and I haven't been successful in finding another solution.

Here's my latest attempt, which doesn't work because the ListChanged event doesn't appear to get raised:

public class EntityCollectionObserver<T> : ObservableCollection<T>, INotifyCollectionChanged where T : class
{
    public event NotifyCollectionChangedEventHandler CollectionChanged;

    public EntityCollectionObserver(EntityCollection<T> entityCollection)
        : base(entityCollection)
    {
        IBindingList l = ((IBindingList)((IListSource)entityCollection).GetList());
        l.ListChanged += new ListChangedEventHandler(OnInnerListChanged);
    }

    private void OnInnerListChanged(object sender, ListChangedEventArgs e)
    {
        if (CollectionChanged != null) 
            CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }
}

Does anyone have any ideas how I might observe changes to an EntityCollection?

Dan


回答1:


have you tried handling AssociationChanged Occurs when a change is made to a related end. (Inherited from RelatedEnd.)

It gives arguments showing whether an element was added or deleted and also exposes the element.




回答2:


Whilst it worked in the simple use case noted by @Aron, I couldn't get it to work properly in my actual application.

As it turns out, and for reasons I'm not sure - the inner IBindingList of an EntityCollection somehow, somewhere, can get changed. The reason my observers weren't being called is because they were looking for changes on an old IBindingList that wasn't even being used by the EntityCollection any more.

Here is the hack that got it working for me:

public class EntityCollectionObserver<T> : ObservableCollection<T> where T : class
{
    private static List<Tuple<IBindingList, EntityCollection<T>, EntityCollectionObserver<T>>> InnerLists 
        = new List<Tuple<IBindingList, EntityCollection<T>, EntityCollectionObserver<T>>>();

    public EntityCollectionObserver(EntityCollection<T> entityCollection)
        : base(entityCollection)
    {
        IBindingList l = ((IBindingList)((IListSource)entityCollection).GetList());
        l.ListChanged += new ListChangedEventHandler(OnInnerListChanged);


        foreach (var x in InnerLists.Where(x => x.Item2 == entityCollection && x.Item1 != l))
        {
            x.Item3.ObserveThisListAswell(x.Item1);
        }
        InnerLists.Add(new Tuple<IBindingList, EntityCollection<T>, EntityCollectionObserver<T>>(l, entityCollection, this));
    }

    private void ObserveThisListAswell(IBindingList l)
    {
        l.ListChanged += new ListChangedEventHandler(OnInnerListChanged);
    }

    private void OnInnerListChanged(object sender, ListChangedEventArgs e)
    {
        base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }
}



回答3:


How are you mapping the event? Pasting your code and mapping the event like follows works for me.

static void Main(string[] args)
    {
        EntityCollection<string> col = new EntityCollection<string>();
        EntityCollectionObserver<string> colObserver = new EntityCollectionObserver<string>(col);

        colObserver.CollectionChanged += colObserver_CollectionChanged;

        col.Add("foo");
    }

    static void colObserver_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        Console.WriteLine("Entity Collection Changed");
    }


来源:https://stackoverflow.com/questions/5502698/entityframework-entitycollection-observing-collectionchanged

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!