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 m开发者_Python百科ight observe changes to an EntityCollection
?
Dan
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.
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));
}
}
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");
}
精彩评论