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
source to share
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;
}
}
source to share