0

DataGridにバインドしているBindingList(T)から継承するカスタム クラスがあります。

ただし、DataGridは上から下に移入されており、下から上に移入したいと考えています。したがって、一番上のアイテムではなく、一番下のアイテムがインデックス 0 になります。

DataGridが逆方向に読み取るようにBindingList(T)を変更するにはどうすればよいですか?

4

4 に答える 4

2

ソート可能なBindingListの実装に関するCodeProject.comのこの記事が役立つ場合があります。

それはそれをソート可能にするバインディングリストのための素晴らしい汎用ラッパーを持っています:

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();
    }
}
于 2009-08-04T02:07:51.760 に答える
0

の IBindingList インターフェイス実装で ApplySort メソッドを呼び出さないのはなぜBindingList<T>ですか? 2 番目のパラメーターに ListSortDirection.Descending の値を渡すだけで、DataGrid は項目を逆順に表示する必要があります。

于 2009-08-04T02:15:53.527 に答える
0

リストが Collection クラスから継承されている場合は、Insert(0,item) メソッドを使用してリストの先頭に挿入できます。そうすれば、最新の要素が一番上に表示されます。ただし、BindingList がこれをサポートしているかどうかはわかりません。

于 2009-10-15T14:30:12.870 に答える
0

シンプルですが、バインドリストを逆の順序で入力することもできます (現在の順序を維持する別の理由がない限り)。

于 2009-08-04T02:13:15.167 に答える