DataGridView / IBindingList排序方向问题

时间:2011-01-18 19:05:45

标签: c# winforms data-binding sorting datagridview

我有一个绑定到BindingSource的DataGridView,它又绑定到提供排序的IBindingList的自定义实现。我的DataGridView列设置为支持自动排序。我期望的行为是,当我第一次点击列标题时,列表将按照相应的列(以我的ApplySortCore逻辑为准)按升序方向排序,排序方向图标将显示为指示上升方向。我希望第二次点击会导致搜索下降,方向图标会切换以反映新的方向。

发生的事情是,当我第一次单击某列时,该列按照该列的升序排序,但排序方向图标不会出现。第二次单击列标题时,再次请求升序排序(在ApplySortCore中使用断点确认),并且列标题中将显示升序排序方向图标。第三次单击列标题时,请求降序排序,但升序排序图标仍显示在列标题中。我第四次单击时,会请求另一个降序排序,并显示降序排序图标。循环继续,以使实际的排序方向每隔一次更改一次,排序方向图标只需单击一次就会滞后于实际的排序方向。

似乎DataGridView(或BindingSource)没有正确跟踪排序方向,因此错误地请求了IBindingList ApplySortCore方法的各种类型。

我正在使用的IBindingList实现来自这个抽象类:

internal abstract class CustomSortableBindingList<T> : BindingList<T>
{
    private bool m_isSorted;
    private ListSortDirection m_sortDirection;
    private PropertyDescriptor m_sortProperty;
    private IComparer<T> m_currentComparer;

    protected CustomSortableBindingList()
    {
    }

    protected CustomSortableBindingList(IList<T> items)
        : base(items)
    {
    }

    protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction)
    {
        var comparer = GetComparer(property, direction);

        Sort(comparer);
        m_sortDirection = direction;
        m_sortProperty = property;
        CurrentComparer = comparer;
    }

    protected abstract IComparer<T> GetComparer(PropertyDescriptor property, ListSortDirection direction);

    protected override void RemoveSortCore()
    {
        m_isSorted = false;
    }

    protected override bool SupportsSortingCore
    {
        get { return true; }
    }

    protected override bool IsSortedCore
    {
        get { return m_isSorted; }
    }

    protected override ListSortDirection SortDirectionCore
    {
        get { return m_sortDirection; }
    }

    protected override PropertyDescriptor SortPropertyCore
    {
        get { return m_sortProperty; }
    }

    public IComparer<T> CurrentComparer
    {
        get { return m_currentComparer; }
        set { m_currentComparer = value; }
    }

    public void Sort(IComparer<T> comparer)
    {
        var items = Items as List<T>;
        if ((null != items) && (null != comparer))
        {
            items.Sort(comparer);
            m_isSorted = true;
            CurrentComparer = comparer;
        }
        else
        {
            m_isSorted = false;
        }
        // Let bound controls know they should refresh their views
        OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));            
    }
}

具体类的GetComparer()方法只包含一个基于属性描述符中指定的名称的switch语句,返回正确的IComparer:

protected override IComparer<HostListItem> GetComparer(PropertyDescriptor property, ListSortDirection direction)
    {
        switch (property.Name)
        {
            case "SomeProperty":
                return new SomePropertyComparer(direction, CurrentComparer);

            default:
                return null;
        }
    }

CurrentComparer属性用于支持嵌套排序。

我已经尝试将DataGridView直接绑定到IBindingList(切掉BindingSource,因为它似乎并没有提供任何额外的功能),但没有任何改变。

有没有人知道为什么DataGridView似乎无法显示正确的排序方向图标或为排序调用提供正确的排序方向?

1 个答案:

答案 0 :(得分:0)

是的,

问题是您在排序完成后触发了ListChanged事件,这会重置排序顺序。