2014-11-14 184 views
3

我需要更新從另外一個一個的ObservableCollection如下面的例子一個的ObservableCollection:在集合體B更新從其他集合

更新的ObservableCollection A和數據:

ObservableCollection<Category> A = new ObservableCollection<Category>() 
{ 
    new Category() 
     { 
     ID = 1, 
     Name = ABC 
     }, 
    new Category() 
     { 
     ID = 4, 
     Name = UVW 
     }, 
    new Category() 
     { 
     ID = 2, 
     Name = DEF 
     }, 
    new Category() 
     { 
     ID = 3, 
     Name = XYZ 
     } 
} 

ObservableCollection<Category> B = new ObservableCollection<Category>() 
{ 
    new Category() 
     { 
     ID = 1, 
     Name = ABC 
     }, 
    new Category() 
     { 
     ID = 5, 
     Name = LMN 
     }, 
    new Category() 
     { 
     ID = 7, 
     Name = GHI 
     }, 
    new Category() 
     { 
     ID = 3, 
     Name = XYZ 
     } 
} 

更新的ObservableCollection一個它應該包含後與B相同的數據,因爲我已經將這個列表綁定到UI列表元素,我不希望它清除,然後逐個添加所有元素,它在用戶體驗中看起來很奇怪。那麼是否有任何優化的LINQ只是遍歷兩個Collection中的所有元素,並使用List B的元素更新列表A

+0

什麼'A = B;'? –

+0

更新A像這樣會更新整個列表,因爲它的綁定和數據可能在導致UI掛起一點點的列表中都很大。這就是爲什麼我在綁定集合後每次添加每個項目的原因。 –

+0

[使用LINQ將值從一個列表分配給另一個列表](http://stackoverflow.com/questions/9708266/assign-values-from-one-list-to-another-using-linq) –

回答

1

您可以訂閱A的集合更改。我已經根據this article的陳述基於以下實現。我無法確保它在全面運作,因爲我不願意測試每一個可能的收集操作。

訂閱A的變化(實例化後):

A.CollectionChanged += A_CollectionChanged; 

B執行同步操作:

private void A_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    switch (e.Action) 
    { 
     case NotifyCollectionChangedAction.Add: 
      //If index is defined; insert. 
      if (e.NewStartingIndex >= 0) 
      { 
       var index = e.NewStartingIndex; 
       foreach (var item in e.NewItems) 
       { 
        B.Insert(index, item as Category); 
        index++; 
       } 
      } 
      //Else; add. 
      else 
       foreach (var item in e.NewItems) 
        B.Add(item as Category); 
      break; 
     case NotifyCollectionChangedAction.Move: 
      //Remove old items at old index first. 
      var oldIndex = e.OldStartingIndex; 
      for (int i = 0; i < e.OldItems.Count; i++) 
      { 
       B.RemoveAt(oldIndex); 
       oldIndex++; 
      } 
      //Then add new items at new index. 
      var newIndex = e.NewStartingIndex; 
      for (int i = 0; i < e.NewItems.Count; i++) 
      { 
       B.RemoveAt(newIndex); 
       newIndex++; 
      } 
      break; 
     case NotifyCollectionChangedAction.Remove: 
      //If remove index is defined; remove at index (safe in case item reference appears in collection multiple times) 
      if (e.OldStartingIndex >= 0) 
      { 
       var index = e.OldStartingIndex; 
       foreach (var item in e.OldItems) 
       { 
        B.RemoveAt(index); 
        index++; 
       } 
      } 
      //Else remove item. 
      else 
       foreach (var item in e.OldItems) 
        B.Remove(item as Category); 
      break; 
     case NotifyCollectionChangedAction.Replace: 
      //If replace index is defined. 
      if (e.NewStartingIndex >= 0) 
      { 
       var index = e.NewStartingIndex; 
       foreach (var item in e.NewItems) 
       { 
        B[index] = item as Category; 
        index++; 
       } 
      } 
      //Else try to find index. 
      else 
       for (int i = 0; i < e.OldItems.Count; i++) 
       { 
        var index = B.IndexOf(e.OldItems[i] as Category); 
        B[index] = e.NewItems[i] as Category; 
       } 
      break; 
     case NotifyCollectionChangedAction.Reset: 
      //Reset collection. 
      B.Clear(); 
      foreach (var item in sender as ObservableCollection<Category>) 
       B.Add(item); 
      break; 
    } 
}