开发winform中,平时经常用到数据列表,我们大多选用datagridview,但是此控件本身没有排序的功能。参阅网上资料。留下标记,以后备用。
datagridview的数据显示一般是通过数据绑定来实现,
即:this.datagridview.DataSource=this.bindingSrc;
this.bindingSrc.DataSource=this.Model;
这种形式就完成了,数据的显示过程。但是要实现点击datagridview实现排序的功能,需要实现对数据源排序的功能。具体代码如下:
public class SortableBindingList<T> : BindingList<T>{private bool isSortedCore = true;private ListSortDirection sortDirectionCore = ListSortDirection.Ascending;private PropertyDescriptor sortPropertyCore = null;private string defaultSortItem;public SortableBindingList() : base() { }public SortableBindingList(IList<T> list) : base(list) { }protected override bool SupportsSortingCore{get { return true; }}protected override bool SupportsSearchingCore{get { return true; }}protected override bool IsSortedCore{get { return isSortedCore; }}protected override ListSortDirection SortDirectionCore{get { return sortDirectionCore; }}protected override PropertyDescriptor SortPropertyCore{get { return sortPropertyCore; }}protected override int FindCore(PropertyDescriptor prop, object key){for (int i = 0; i < this.Count; i++){if (Equals(prop.GetValue(this[i]), key)) return i;}return -1;}protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction){isSortedCore = true;sortPropertyCore = prop;sortDirectionCore = direction;Sort();}protected override void RemoveSortCore(){if (isSortedCore){isSortedCore = false;sortPropertyCore = null;sortDirectionCore = ListSortDirection.Ascending;Sort();}}public string DefaultSortItem{get { return defaultSortItem; }set{if (defaultSortItem != value){defaultSortItem = value;Sort();}}}private void Sort(){List<T> list = (this.Items as List<T>);list.Sort(CompareCore);ResetBindings();}private int CompareCore(T o1, T o2){int ret = 0;if (SortPropertyCore != null){ret = CompareValue(SortPropertyCore.GetValue(o1), SortPropertyCore.GetValue(o2), SortPropertyCore.PropertyType);}if (ret == 0 && DefaultSortItem != null){PropertyInfo property = typeof(T).GetProperty(DefaultSortItem, BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.IgnoreCase, null, null, new Type[0], null);if (property != null){ret = CompareValue(property.GetValue(o1, null), property.GetValue(o2, null), property.PropertyType);}}if (SortDirectionCore == ListSortDirection.Descending) ret = -ret;return ret;}private static int CompareValue(object o1, object o2, Type type){if (o1 == null) return o2 == null ? 0 : -1;else if (o2 == null) return 1;else if (type.IsPrimitive || type.IsEnum) return Convert.ToDouble(o1).CompareTo(Convert.ToDouble(o2));else if (type == typeof(DateTime)) return Convert.ToDateTime(o1).CompareTo(o2);else return String.Compare(o1.ToString().Trim(), o2.ToString().Trim());}}
实现此类后,就可以通过 this.bindingSrc.DataSource=new SortableBindingList<CnsDetailReport>(this.Model); 实现点击列标题排序的目的了。