5 votes

EntityFramework EntityCollection Observing CollectionChanged

J'utilise d'abord la base de données EntityFramework dans une application. J'aimerais d'une manière ou d'une autre être notifié des modifications apportées à une base de données EntityFramework. EntityCollection dans mon ViewModel. Il ne supporte pas directement INotifyCollectionChanged (pourquoi ?) et je n'ai pas réussi à trouver une autre solution.

Voici ma dernière tentative, qui ne fonctionne pas parce que le bouton ListChanged L'événement ne semble pas être levé :

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

Quelqu'un a-t-il une idée de la manière dont je pourrais observer les changements apportés à un système de gestion de l'eau ? EntityCollection ?

Dan

3voto

DermFrench Points 879

Avez-vous essayé de manipuler AssociationChanged Se produit lorsqu'une modification est apportée à une extrémité connexe. (Hérité de RelatedEnd.)

Il donne des arguments montrant si un élément a été ajouté ou supprimé et expose également l'élément.

2voto

Daniel Skinner Points 999

Bien que cela ait fonctionné dans le cas d'utilisation simple mentionné par @Aron, je n'ai pas réussi à le faire fonctionner correctement dans mon application réelle.

Il s'avère, et pour des raisons que je ne connais pas bien, que l'intérieur IBindingList d'un EntityCollection d'une manière ou d'une autre, quelque part, peut être changée. La raison pour laquelle mes observateurs n'ont pas été appelés est qu'ils cherchaient des changements sur une vieille IBindingList qui n'était même pas utilisé par le EntityCollection plus.

Voici le hack qui a permis de le faire fonctionner pour moi :

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

1voto

Aron W. Points 83

Comment cartographiez-vous l'événement ? Coller votre code et mapper l'événement comme suit fonctionne pour moi.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X