【问题标题】:WPF - Using a custom comparer when sorting by multiple columnsWPF - 按多列排序时使用自定义比较器
【发布时间】:2011-08-01 02:16:48
【问题描述】:

我有一个 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 的字符串(属性类型)...

有人知道怎么做吗?

【问题讨论】:

    标签: c# wpf vb.net sorting listview


    【解决方案1】:

    您的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 以支持多列排序,我用谷歌搜索并发现this comparer implementation 您可以为其提供几个用逗号分隔并以ASC/DESC 为后缀的属性路径,如下所示:

    User.LastName DESC, User.FirstName DESC
    

    我认为就 UI 而言,多列排序的惯例是您需要按住 Ctrl 按钮。因此子类化 ListView 类并绑定到 GridViewColumnHeader clicked 事件和 KeyDown 事件,以了解连续点击了哪些列,然后使用 IComparer 实现将其输入。

    【讨论】:

    • 这在按一列排序时有效,但由于 PropertyPath 指的是被点击的列(在我的代码中也是 sortHeader),即使它应该比较第二列,它也会查看该列列(第二个 SortDescription)。比较器如何知道它应该查看第一列(点击的那一列)还是第二列(当第 1 列中有 2+ 具有相同值时)?
    • 在上面进行了一些更改以尝试回答您的确切问题:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    • 2023-04-06
    • 2016-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多