1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;
namespace CM.Utility.Collections
{
[Serializable()]
public class SortableBindingList<T>: BindingList<T>, ITypedList
{
[NonSerialized()]
private PropertyDescriptorCollection properties;
public SortableBindingList()
: base()
{
// Get the 'shape' of the list.
// Only get the public properties marked with Browsable = true.
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(
typeof(T),
new Attribute[] { new BrowsableAttribute(true) });
// Sort the properties.
properties = pdc.Sort();
}
#region ITypedList Implementation
public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
{
PropertyDescriptorCollection pdc = null;
if( null == listAccessors )
{
// Return properties in sort order.
pdc = properties;
} else
{
// Return child list shape.
pdc = ListBindingHelper.GetListItemProperties(listAccessors[0].PropertyType);
}
return pdc;
}
// This method is only used in the design-time framework
// and by the obsolete DataGrid control.
public string GetListName(PropertyDescriptor[] listAccessors)
{
return typeof(T).Name;
}
protected override bool SupportsSortingCore
{
get
{
return true;
}
}
protected override bool IsSortedCore
{
get
{
return base.IsSortedCore;
}
}
protected override PropertyDescriptor SortPropertyCore
{
get
{
return base.SortPropertyCore;
}
}
protected override ListSortDirection SortDirectionCore
{
get
{
return base.SortDirectionCore;
}
}
protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
List<T> helper = (List<T>)this.Items;
this.currentProperty = prop;
this.currentDirection = direction;
helper.Sort(Compare);
}
[NonSerialized]
private PropertyDescriptor currentProperty;
[NonSerialized]
private ListSortDirection currentDirection;
private int Compare(T a, T b)
{
object valA = currentProperty.GetValue(a);
object valB = currentProperty.GetValue(b);
IComparable icA = valA as IComparable;
IComparable icB = valB as IComparable;
if( icA == null && icB == null )
{
return 0;
}
if( icA == null && icB != null )
{
return currentDirection == ListSortDirection.Ascending ? -1 : 1;
}
if( icA != null && icB == null )
{
return currentDirection == ListSortDirection.Ascending ? 1 : -1;
}
if( currentDirection == ListSortDirection.Ascending )
{
return icA.CompareTo(icB);
} else
{
return -icA.CompareTo(icB);
}
}
protected override void RemoveSortCore()
{
}
#endregion
public void AddRange(IEnumerable<T> itemsToAdd)
{
foreach( T item in itemsToAdd )
{
this.Add(item);
}
}
}
}
|