5

我在應用程序中首先使用EntityFramework數據庫。我想以某種方式被通知在我的ViewModel中對EntityCollection的更改。它不直接支持INotifyCollectionChanged(爲什麼?),我還沒有成功找到另一種解決方案。EntityFramework EntityCollection觀察CollectionChanged

這裏是我的最新嘗試,因爲ListChanged事件似乎並沒有引起人們的關注不工作:

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

有沒有人有我怎麼可能會觀察到變化的EntityCollection任何想法?

+0

另請參閱http://stackoverflow.com/questions/6264979/changing-association-property-entitycollection-dont-rise-propertychanged – OneWorld 2013-01-14 10:20:52

回答

2

雖然它在@Aron指出的簡單用例中工作,但我無法在我的實際應用程序中正常工作。

事實證明,由於原因我不確定 - 在某個地方EntityCollection的內部IBindingList可以改變。我的觀察員沒有被叫的原因是因爲他們正在尋找一箇舊的IBindingList的變化,甚至沒有被EntityCollection使用。

這裏是得到它的工作對我來說黑客:

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

男人,這似乎很多工作......我想知道內部列表如何變化。你是不是在外面改變它?太奇怪了。 – 2011-04-22 20:20:06

+0

我從來沒有找到什麼時候或爲什麼要改變。由於即使上述解決方案不可靠,也不需要監視內部列表何時更改。 我現在已經遷移到STE,並且正在愉快地使用TrackableCollection。 – djskinner 2011-04-26 11:55:48

1

您是如何映射事件的?粘貼您的代碼並將事件映射如下,適用於我。

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

工程!不知道我以前做錯了什麼。 – djskinner 2011-04-06 08:45:45

+0

事實證明,它並不適用於所有情況。請參閱下面的答案,瞭解適用於我的解決方案。 – djskinner 2011-04-13 13:37:31

2

你試圖處理 AssociationChanged當一個變化的相關完發發生。 (繼承自RelatedEnd。)

它給出的參數顯示元素是否被添加或刪除,並且還暴露元素。