【问题标题】:Reverse sort a BindingList<T>对 BindingList<T> 进行反向排序
【发布时间】:2009-08-04 01:30:18
【问题描述】:

我有一个继承自 BindingList(T) 的自定义类,我将其绑定到 DataGrid

但是,DataGrid 是自上而下填充的,我希望它是自下而上填充的。所以底部项目是索引 0 而不是顶部项目。

如何更改我的 BindingList(T) 以便 DataGrid 反向读取它?

【问题讨论】:

    标签: c# sorting datagrid bindinglist


    【解决方案1】:

    ThisCodeProject.com 上关于实现可排序 BindingList 的文章可能会对您有所帮助。

    它有一个很好的用于绑定列表的通用包装器,使其可排序:

    public class MySortableBindingList<T> : BindingList<T> {
    
        // reference to the list provided at the time of instantiation
        List<T> originalList;
        ListSortDirection sortDirection;
        PropertyDescriptor sortProperty;
    
        // function that refereshes the contents
        // of the base classes collection of elements
        Action<MySortableBindingList<T>, List<T>> 
                       populateBaseList = (a, b) => a.ResetItems(b);
    
        // a cache of functions that perform the sorting
        // for a given type, property, and sort direction
        static Dictionary<string, Func<List<T>, IEnumerable<T>>> 
           cachedOrderByExpressions = new Dictionary<string, Func<List<T>, 
                                                     IEnumerable<T>>>();
    
        public MySortableBindingList() {
            originalList = new List<T>();
        }
    
        public MySortableBindingList(IEnumerable<T> enumerable) {
            originalList = enumerable.ToList();
            populateBaseList(this, originalList);
        }
    
        public MySortableBindingList(List<T> 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<T>.
             Cache it.
            */
    
            var sourceParameter = Expression.Parameter(typeof(List<T>), "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 => a.Name == orderByMethodName &&
                                                       a.GetParameters().Length == 2)
                                          .Single()
                                          .MakeGenericMethod(typeof(T), prop.PropertyType);
    
            var orderByExpression = Expression.Lambda<Func<List<T>, IEnumerable<T>>>(
                                        Expression.Call(orderByMethod,
                                                new Expression[] { sourceParameter, 
                                                                   propertySelectorLambda }),
                                                sourceParameter);
    
            cachedOrderByExpressions.Add(cacheKey, orderByExpression.Compile());
        }
    
        protected override void RemoveSortCore() {
            ResetItems(originalList);
        }
    
        private void ResetItems(List<T> items) {
    
            base.ClearItems();
    
            for (int i = 0; i < 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();
        }
    }
    

    【讨论】:

      【解决方案2】:

      这很简单,但您也可以按相反的顺序填充绑定列表(除非您有其他理由保持当前顺序)。

      【讨论】:

      • 我没有以图表方式填充列表,用户正在通过 DataGrid 填充列表。网格的每一行代表建筑物的楼层。所以我希望较低的楼层显示在底部,而较高的楼层显示在顶部。我想颠倒顺序,以便我可以按楼层号引用列表中的楼层,其中 floorIndex = floor number-1
      • 现在这是有用的信息 - 请将其添加到问题中。它应该有助于获得更好的答案。这是用户执行“添加新行”之类的问题吗?
      【解决方案3】:

      为什么不在BindingList&lt;T&gt;上的IBindingList接口实现上调用ApplySort方法呢?您可以只为第二个参数传递 ListSortDirection.Descending 的值,DataGrid 应该以相反的顺序显示项目。

      【讨论】:

      • 每当我从列表中添加或删除项目时,是否需要重新应用排序?或者它会记得保持降序排序吗?
      • @Eric 我不明白为什么它不会保持排序顺序,但它很容易测试。
      【解决方案4】:

      如果您的列表继承自 Collection 类,您可以使用 Insert(0,item) 方法插入到列表的开头。这样最新的元素就会出现在顶部。不过不确定 BindingList 是否支持。

      【讨论】:

        猜你喜欢
        • 2017-02-04
        • 1970-01-01
        • 2017-06-05
        • 2017-09-20
        • 2010-09-19
        • 2021-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多