BindingList Extensions


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

Advertisement
This entry was posted in C#, Syntax and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s