2011-01-18 2 views
1

BindingSource에 바인딩 된 DataGridView가 있습니다. BindingSource는 차례대로 정렬을 제공하는 IBindingList의 사용자 지정 구현에 바인딩됩니다. 내 DataGridView 열은 자동 정렬을 지원하도록 설정됩니다. 예상되는 동작은 열 머리글을 처음 클릭 할 때 목록이 오름차순으로 해당 열 (내 ApplySortCore 논리에 따라 정렬 됨)에 정렬되고 오름차순 방향을 나타내는 정렬 방향 아이콘이 나타납니다. 두 번째 클릭으로 인해 내림차순 검색이 발생하고 방향 아이콘이 새로운 방향을 반영하여 전환 될 것으로 기대됩니다.DataGridView/IBindingList 방향 문제 정렬

처음 열을 클릭하면 해당 열로 목록이 오름차순으로 정렬되지만 정렬 방향 아이콘은 나타나지 않습니다. 두 번째로 열 머리글을 클릭하면 오름차순 정렬이 다시 요청되고 (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() 메소드는 단순히 반환, 속성 설명에 지정된 이름에 따라 스위치 문을 포함 올바른 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

어떤 시점에서 예외가 발생하지 않는다고 100 % 확신합니까? 그것은 이상한 점을 설명 할 수 있습니다 ... 또한 IsSorted에 대한 귀하의 목록 보고서는 무엇입니까? (다시 코드가 완료되었는지 확인하려고합니다.) –

+0

예외가 발생하지 않고 ApplySortCore 메서드를 통해 방금 밟았습니다. 결국 IsSortedCore 속성 (m_isSorted)이 true입니다. 또한, 나는 ApplySortCore에 대한 호출 후에 발생하는 ColumnHeaderMouseClick에 대한 핸들러에 중단 점을 설정합니다. 이 시점에서 BindingSource의 IsSorted 속성도 true입니다. –

+0

이상한. IBindingList 구현 끝에서 OnListChanged 호출을 제거하면 문제가 해결됩니다. 내가 왜 문제가 발생했는지 전혀 알지 못하기 때문에 대답으로 입력하지 않습니다. –

답변

0

네는

문제 정렬이 완료된 후 정렬 순서를 재설정 할 것이다는의 ListChanged 이벤트를 트리거하는 것이있다.