【问题标题】:Update one observableCollection from other collection从其他集合更新一个 observableCollection
【发布时间】:2014-11-14 07:16:18
【问题描述】:

我需要从另一个更新一个 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 A 后,它应该包含与 B 相同的数据,由于我已将此列表绑定到 UI 列表元素,我不希望它清除,然后一一添加所有元素,这在用户体验中看起来很奇怪.那么是否有任何优化的 LINQ 只遍历两个集合中的所有元素并使用列表 B 的元素更新列表 A

【问题讨论】:

  • 更新 A 像这样将更新整个列表,因为列表中的绑定和数据可能很大,导致 UI 有点挂起。这就是我在绑定集合后一次添加每个项目的原因。

标签: c# wpf linq observablecollection


【解决方案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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-04
    相关资源
    最近更新 更多