So when working with binding lists you often have a scenario where you have to update the list you have with the list from the database. If you want to make sure that the selections that a user may have on the UI will be retained you have to make sure that the items are not removed and re-added.
These extensions are intended to accomplish that task.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace Foo
{
public static class BindingListExtensions
{
public static void QuietMerge(this BindingList source, IEnumerable update, IEqualityComparer Matcher)
{
source.RaiseListChangedEvents = false;
source.Merge(update, Matcher);
source.RaiseListChangedEvents = true;
source.ResetBindings();
}
public static void Merge(this BindingList source, IEnumerable update, IEqualityComparer Matcher)
{
List targetlist;
targetlist = new List(source);
targetlist.Reverse();
// trim the list, and update the existing values
var removes = targetlist.Except(update, Matcher);
foreach (T w in targetlist.Except(update,Matcher))
source.Remove(w);
foreach (var w in targetlist.Except(removes).Join(source, x => x, x => x, (x, y) => new { tl = x, sl = y }, Matcher))
{
w.sl.MergeDataByReflection(w.tl);
}
// add new entries.
targetlist =
new List(source);
foreach (T w in update.Except(targetlist, Matcher))
{
source.Add(w);
}
}
static public void MergeDataByReflection(this T merged, T original)
{
merged.MergeDataByReflection(original, new List());
}
static public void MergeDataByReflection(this T merged, T original, IEnumerable ignoreList)
{
var PropsToSet = typeof(T).GetProperties().Where(x =>!ignoreList.Contains(x.Name));
foreach (var prop in PropsToSet.Where(x=>x.CanWrite))
{
prop.SetValue(
merged,
prop.GetValue(original, null),
null);
}
}
}
}
And in case you don’t want to write all the comparers then here is something that allows you to do it with lambda
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Foo
{
public class EqualityComparer : IEqualityComparer
{
public EqualityComparer(CommonDelegates.Test test, CommonDelegates.HashCode hashcode)
{
Test = test;
Hashcode = hashcode;
}
CommonDelegates.Test Test;
CommonDelegates.HashCode Hashcode;
public bool Equals(T x, T y)
{
return Test.Invoke(x, y);
}
public int GetHashCode(T obj)
{
return Hashcode.Invoke(obj);
}
}
public class CommonDelegates
{
public delegate bool Test(T x, T y);
public delegate int HashCode(T x);
}
}