WPF -在按多列排序时使用自定义比较器
本文关键字:自定义 比较器 排序 WPF | 更新日期: 2023-09-27 17:49:15
我有一个ListView (GridView),我想按2列排序,所以如果2+项在列1中具有相同的值,它按列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的值(这是它真正应该关心的,因为这是它排序的依据)。
比较器如何知道要比较哪个属性?也许我做错了什么,因为这没有任何意义。我希望得到一个字符串(属性类型)的x和y…
有人知道怎么做吗?
您的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
以支持多列排序,我在谷歌上搜索并找到了这个比较器实现,您可以为它提供几个由逗号分隔的属性路径,并以ASC/DESC为后缀,如下所示:
User.LastName DESC, User.FirstName DESC
我认为就UI而言,多列排序的约定是您需要按住Ctrl
按钮。所以子类ListView类和绑定到GridViewColumnHeader click事件和KeyDown事件,以了解哪些列被连续单击,然后使用IComparer
实现将其馈送到。