Updating one observable set from another collection

I need to update one observable collection from another like below:

Update ObservableCollection A with data in collection B:

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

      

After updating ObservableCollection A, it should contain the same data as B. Since I have bound this list to a UI list item, I do not want to clear it and then add all the items one by one, which will look strange in the user experience. , is there an optimized LINQ to just iterate over all elements in two collection lists and update A with list element B

+3


source to share


1 answer


You can subscribe to collection changes A

. I based the following implementation in the expressions of this article . I cannot make it work completely as I have been rather reluctant to test every possible collection manipulation.

Subscribe to changes A

(after creating it):

A.CollectionChanged += A_CollectionChanged;

      



Follow the sync steps on 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;
    }
}

      

+1


source







All Articles