Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><a href="http://www.codeproject.com/KB/linq/bindinglist_sortable.aspx" rel="nofollow noreferrer">This</a> article on <a href="http://www.codeproject.com" rel="nofollow noreferrer">CodeProject.com</a> about implementing sortable BindingList might help you.</p> <p>It has a nice generic wrapper for binding list that makes it sortable:</p> <pre><code>public class MySortableBindingList&lt;T&gt; : BindingList&lt;T&gt; { // reference to the list provided at the time of instantiation List&lt;T&gt; originalList; ListSortDirection sortDirection; PropertyDescriptor sortProperty; // function that refereshes the contents // of the base classes collection of elements Action&lt;MySortableBindingList&lt;T&gt;, List&lt;T&gt;&gt; populateBaseList = (a, b) =&gt; a.ResetItems(b); // a cache of functions that perform the sorting // for a given type, property, and sort direction static Dictionary&lt;string, Func&lt;List&lt;T&gt;, IEnumerable&lt;T&gt;&gt;&gt; cachedOrderByExpressions = new Dictionary&lt;string, Func&lt;List&lt;T&gt;, IEnumerable&lt;T&gt;&gt;&gt;(); public MySortableBindingList() { originalList = new List&lt;T&gt;(); } public MySortableBindingList(IEnumerable&lt;T&gt; enumerable) { originalList = enumerable.ToList(); populateBaseList(this, originalList); } public MySortableBindingList(List&lt;T&gt; list) { originalList = list; populateBaseList(this, originalList); } protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction) { /* Look for an appropriate sort method in the cache if not found . Call CreateOrderByMethod to create one. Apply it to the original list. Notify any bound controls that the sort has been applied. */ sortProperty = prop; var orderByMethodName = sortDirection == ListSortDirection.Ascending ? "OrderBy" : "OrderByDescending"; var cacheKey = typeof(T).GUID + prop.Name + orderByMethodName; if (!cachedOrderByExpressions.ContainsKey(cacheKey)) { CreateOrderByMethod(prop, orderByMethodName, cacheKey); } ResetItems(cachedOrderByExpressions[cacheKey](originalList).ToList()); ResetBindings(); sortDirection = sortDirection == ListSortDirection.Ascending ? ListSortDirection.Descending : ListSortDirection.Ascending; } private void CreateOrderByMethod(PropertyDescriptor prop, string orderByMethodName, string cacheKey) { /* Create a generic method implementation for IEnumerable&lt;T&gt;. Cache it. */ var sourceParameter = Expression.Parameter(typeof(List&lt;T&gt;), "source"); var lambdaParameter = Expression.Parameter(typeof(T), "lambdaParameter"); var accesedMember = typeof(T).GetProperty(prop.Name); var propertySelectorLambda = Expression.Lambda(Expression.MakeMemberAccess(lambdaParameter, accesedMember), lambdaParameter); var orderByMethod = typeof(Enumerable).GetMethods() .Where(a =&gt; a.Name == orderByMethodName &amp;&amp; a.GetParameters().Length == 2) .Single() .MakeGenericMethod(typeof(T), prop.PropertyType); var orderByExpression = Expression.Lambda&lt;Func&lt;List&lt;T&gt;, IEnumerable&lt;T&gt;&gt;&gt;( Expression.Call(orderByMethod, new Expression[] { sourceParameter, propertySelectorLambda }), sourceParameter); cachedOrderByExpressions.Add(cacheKey, orderByExpression.Compile()); } protected override void RemoveSortCore() { ResetItems(originalList); } private void ResetItems(List&lt;T&gt; items) { base.ClearItems(); for (int i = 0; i &lt; items.Count; i++) { base.InsertItem(i, items[i]); } } protected override bool SupportsSortingCore { get { // indeed we do return true; } } protected override ListSortDirection SortDirectionCore { get { return sortDirection; } } protected override PropertyDescriptor SortPropertyCore { get { return sortProperty; } } protected override void OnListChanged(ListChangedEventArgs e) { originalList = base.Items.ToList(); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload