2011-04-07 50 views
5

Tôi có một ListView (GridView) mà tôi muốn sắp xếp theo 2 cột, vì vậy nếu 2+ mục có cùng giá trị trong Cột 1, nó sắp xếp theo Cột 2. Khá dễ dàng. Nhưng các chuỗi rỗng xuất hiện ở đầu khi phân loại A-Z. Tôi muốn chuyển chúng xuống đáy. Tôi đã thực hiện một so sánh (IComparer) mà chăm sóc này, nhưng tôi không chắc chắn làm thế nào để sử dụng nó.WPF - Sử dụng một so sánh tùy chỉnh khi sắp xếp theo nhiều cột

Dưới đây là đoạn code tôi đã cố gắng:

Dim view As ListCollectionView = CollectionViewSource.GetDefaultView(myCollection) 
Using view.DeferRefresh 
    view.SortDescriptions.Clear() 
    view.SortDescriptions.Add(New SortDescription(sortHeader.Header, direction)) 
    view.SortDescriptions.Add(New SortDescription(otherColumn, direction)) 
    view.CustomSort = New MyComparer() 
End Using 

Vấn đề là Comparer của tôi được đưa ra một loại lớp học của tôi thay vì giá trị của tài sản/cột được sắp xếp theo. Vì vậy, nếu lớp học là Foo và tôi đang phân loại bởi Foo.Bar, tôi nhận được toàn bộ lớp Foo, không chỉ là giá trị của Bar (mà thực sự là tất cả những gì cần phải quan tâm, vì đó là những gì nó sắp xếp theo).

Làm cách nào để so sánh của tôi biết được thuộc tính nào cần so sánh? Có lẽ tôi đang làm điều gì đó sai ở đây, bởi vì điều này không có ý nghĩa gì cả. Tôi dự kiến ​​nhận được một Chuỗi (loại tài sản) cho x và y ...

Có ai biết cách thực hiện việc này không?

Trả lời

6

thực hiện IComparer của bạn sẽ được cung cấp toàn bộ đối tượng, bạn cần phải tìm ra những cột được nhấp, có lẽ bằng cách thực hiện một cái gì đó như thế này:

this.AddHandler(GridViewColumnHeader.ClickEvent, 
       new RoutedEventHandler(Column_Sort)); 

và sau đó thức ăn đó vào MyComparer của bạn có thể bằng cách sửa đổi constructor của bạn để đi vào con đường tài sản.

Trong Column_Sort bạn có thể nhận được một cái gì đó con đường bất động sản như thế này (tôi là một chút gỉ trên vb, nhưng phương án C# sẽ làm điều này:.

void Column_Sort(object sender, RoutedEventArgs e) 
{ 
    var memberBinding= ((GridViewColumnHeader)e.OriginalSource).Column.DisplayMemberBinding; 
    var path = ((Binding)memberBinding).Path.Path; 
} 

và sau đó thức ăn đó vào luận lý sắp xếp của bạn

Dim view As ListCollectionView = CollectionViewSource.GetDefaultView(myCollection) 
Using view.DeferRefresh 
    view.SortDescriptions.Clear() 
    view.SortDescriptions.Add(New SortDescription(sortHeader.Header, direction)) 
    view.SortDescriptions.Add(New SortDescription(otherColumn, direction)) 
    view.CustomSort = New MyComparer(PropertyPath) 
End Using 

EDIT: bạn chỉ cần để tùy chỉnh của bạn IComparer để hỗ trợ nhiều cột phân loại, tôi googled và thấy this comparer implementation mà bạn có thể ăn nó severa l đường dẫn bất động sản được phân cách bởi dấu phẩy và hậu tố với ASC/DESC như thế này:

User.LastName DESC, User.FirstName DESC 

Tôi nghĩ quy ước cho nhiều cột sắp xếp như xa như giao diện người dùng là có liên quan là bạn cần phải có nút Ctrl tổ chức. Vì vậy, phân lớp lớp ListView và buộc vào sự kiện GridViewColumnHeader được nhấp và sự kiện KeyDown để biết cột nào được nhấp liên tiếp và sau đó sử dụng triển khai IComparer để nạp vào.

+0

Điều này hoạt động khi sắp xếp theo một cột, nhưng vì PropertyPath đề cập đến cột được nhấp (cũng là sortHeader trong mã của tôi), nó trông giống cột đó ngay cả khi so sánh cột thứ hai (thứ hai SortDescription)). Làm thế nào để so sánh biết nếu nó nên nhìn vào cột đầu tiên (nhấp vào một) hoặc thứ hai (khi có 2+ có cùng giá trị trong cột 1)? – grant

+0

Đã thực hiện một số thay đổi ở trên để thử trả lời cho bạn câu hỏi chính xác :) – Jose

Các vấn đề liên quan