我有一个ListView(GridView),我想按2列排序,所以如果2列中的2个项目具有相同的值,则按列2进行排序。非常简单。但是在排序A-Z时,空字符串显示在顶部。我想将它们移到最底层。我制作了一个比较器(IComparer)来处理这个问题,但我不确定如何使用它。
这是我尝试过的代码:
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
问题是我的比较器被赋予了我的类的类型,而不是被排序的属性/列的值。因此,如果这个类是Foo而我是按Foo.Bar排序的话,我会得到整个Foo类,而不仅仅是Bar的值(这真的是它应该关注的全部,因为它是什么&它#39;按...排序。
我的比较器如何知道要比较哪个属性?也许我在这里做错了,因为这没有任何意义。我希望得到x和y的字符串(属性类型)
有谁知道怎么做?
答案 0 :(得分:7)
您的IComparer
实现将被赋予整个对象,您需要确定哪个列被点击,可能通过这样做:
this.AddHandler(GridViewColumnHeader.ClickEvent,
new RoutedEventHandler(Column_Sort));
然后可能通过修改构造函数将其输入到MyComparer
中以获取属性路径。
在Column_Sort
中,您可以获得类似的属性路径(我在vb上有点生疏,但c#会这样做:
void Column_Sort(object sender, RoutedEventArgs e)
{
var memberBinding= ((GridViewColumnHeader)e.OriginalSource).Column.DisplayMemberBinding;
var path = ((Binding)memberBinding).Path.Path;
}
然后将其提供给您的排序逻辑。
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
修改强>
您只需要自定义IComparer
以支持多列排序,我用Google搜索并找到this comparer implementation,您可以为其提供几个以逗号分隔的属性路径,并以ASC / DESC为后缀,如下所示:
User.LastName DESC, User.FirstName DESC
我认为就UI而言,多列排序的惯例是你需要保持Ctrl
按钮。因此,继承ListView类并将其绑定到GridViewColumnHeader单击事件和KeyDown事件,以了解哪些列已连续单击,然后使用IComparer
实现将其输入。