2014-11-14 138 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; 
    } 
}