5

Estoy utilizando la base de datos EntityFramework primero en una aplicación. Me gustaría de alguna manera ser notificado de los cambios a un EntityCollection en mi ViewModel. No es compatible directamente con INotifyCollectionChanged (¿por qué?) Y no he tenido éxito en encontrar otra solución.EntityFramework EntityCollection Observando CollectionChanged

Aquí es mi último intento, que no funciona porque el evento ListChanged no parece quedar levantado:

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

¿Alguien tiene alguna idea de cómo podría observar cambios en un EntityCollection?

Dan

+0

También vea http://stackoverflow.com/questions/6264979/changing-association-property-entitycollection-dont-rise-propertychanged – OneWorld

Respuesta

2

Si bien funcionó en el caso de uso simple señalado por @Aron, no pude hacer que funcione correctamente en mi aplicación real.

Como resultado, y por razones que no estoy seguro, el IBindingList interior de un EntityCollection de alguna manera, en algún lugar, puede cambiarse. La razón por la que mis observadores no fueron llamados es porque estaban buscando cambios en un viejo IBindingList que ni siquiera estaba siendo usado por el EntityCollection.

Aquí está el truco que tengo trabajo para mí:

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

Hombre, eso parece mucho trabajo ... Me pregunto cómo se está cambiando esa lista interna. ¿No lo estabas cambiando externamente? Tan raro. –

+0

Nunca funcioné cuando o por qué fue cambiado. Como no se debe monitorear cuando se cambia la lista interna, incluso la solución anterior no es confiable. He migrado a STE por el momento y estoy felizmente haciendo uso de TrackableCollection. – djskinner

1

¿Cómo mapea el evento? Pegar tu código y mapear el evento de la siguiente manera me funciona.

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

¡Funciona! No estoy seguro de lo que estaba haciendo mal anteriormente. – djskinner

+0

Como resultado, no funciona en todos los casos. Vea mi respuesta a continuación para una solución que funcionó para mí. – djskinner

2

has necesitado manejo AssociationChanged Se produce cuando se realiza un cambio en un extremo relacionado. (Se hereda de RelatedEnd.)

Proporciona argumentos que muestran si un elemento se agregó o eliminó y también expone el elemento.

Cuestiones relacionadas