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…

有人知道怎么做吗?

WPF -在按多列排序时使用自定义比较器

您的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实现将其馈送到。