Created
September 13, 2013 08:59
-
-
Save tvolodimir/6548282 to your computer and use it in GitHub Desktop.
SortableBindingList C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SortableBindingList<T> : BindingList<T> | |
{ | |
private readonly Dictionary<Type, PropertyComparer<T>> comparers; | |
private bool isSorted; | |
private ListSortDirection listSortDirection; | |
private PropertyDescriptor propertyDescriptor; | |
public SortableBindingList() | |
: base(new List<T>()) | |
{ | |
this.comparers = new Dictionary<Type, PropertyComparer<T>>(); | |
} | |
public SortableBindingList(IEnumerable<T> enumeration) | |
: base(new List<T>(enumeration)) | |
{ | |
this.comparers = new Dictionary<Type, PropertyComparer<T>>(); | |
} | |
protected override bool SupportsSortingCore | |
{ | |
get { return true; } | |
} | |
protected override bool IsSortedCore | |
{ | |
get { return this.isSorted; } | |
} | |
protected override PropertyDescriptor SortPropertyCore | |
{ | |
get { return this.propertyDescriptor; } | |
} | |
protected override ListSortDirection SortDirectionCore | |
{ | |
get { return this.listSortDirection; } | |
} | |
protected override bool SupportsSearchingCore | |
{ | |
get { return true; } | |
} | |
protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction) | |
{ | |
List<T> itemsList = (List<T>)this.Items; | |
Type propertyType = property.PropertyType; | |
PropertyComparer<T> comparer; | |
if (!this.comparers.TryGetValue(propertyType, out comparer)) | |
{ | |
comparer = new PropertyComparer<T>(property, direction); | |
this.comparers.Add(propertyType, comparer); | |
} | |
comparer.SetPropertyAndDirection(property, direction); | |
itemsList.Sort(comparer); | |
this.propertyDescriptor = property; | |
this.listSortDirection = direction; | |
this.isSorted = true; | |
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); | |
} | |
protected override void RemoveSortCore() | |
{ | |
this.isSorted = false; | |
this.propertyDescriptor = base.SortPropertyCore; | |
this.listSortDirection = base.SortDirectionCore; | |
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); | |
} | |
protected override int FindCore(PropertyDescriptor property, object key) | |
{ | |
int count = this.Count; | |
for (int i = 0; i < count; ++i) | |
{ | |
T element = this[i]; | |
if (property.GetValue(element).Equals(key)) | |
{ | |
return i; | |
} | |
} | |
return -1; | |
} | |
} | |
public class PropertyComparer<T> : IComparer<T> | |
{ | |
private readonly IComparer comparer; | |
private PropertyDescriptor propertyDescriptor; | |
private int reverse; | |
public PropertyComparer(PropertyDescriptor property, ListSortDirection direction) | |
{ | |
this.propertyDescriptor = property; | |
Type comparerForPropertyType = typeof(Comparer<>).MakeGenericType(property.PropertyType); | |
this.comparer = (IComparer)comparerForPropertyType.InvokeMember("Default", BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.Public, null, null, null); | |
this.SetListSortDirection(direction); | |
} | |
#region IComparer<T> Members | |
public int Compare(T x, T y) | |
{ | |
return this.reverse * this.comparer.Compare(this.propertyDescriptor.GetValue(x), this.propertyDescriptor.GetValue(y)); | |
} | |
#endregion | |
private void SetPropertyDescriptor(PropertyDescriptor descriptor) | |
{ | |
this.propertyDescriptor = descriptor; | |
} | |
private void SetListSortDirection(ListSortDirection direction) | |
{ | |
this.reverse = direction == ListSortDirection.Ascending ? 1 : -1; | |
} | |
public void SetPropertyAndDirection(PropertyDescriptor descriptor, ListSortDirection direction) | |
{ | |
this.SetPropertyDescriptor(descriptor); | |
this.SetListSortDirection(direction); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment