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

问题描述:

我有一个ListView(GridView的),我想通过2列进行排序,因此,如果2+项在第1列的值相同,它按列2 pretty容易。但空字符串顶部分拣A-Z时出现。我想将其移动到下方。我做了一个比较器(IComparer的)那需要照顾这一点,但我不知道如何使用它。

I have a ListView (GridView) that I want to sort by 2 columns, so if 2+ items have the same value in Column 1, it sorts by Column 2. Pretty easy. But empty strings show up at the top when sorting A-Z. I'd like to move them to the bottom. I made a comparer (IComparer) that takes care of this, but I'm not sure how to use it.

这里的code我尝试:

Here's the code I tried:

 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类,而不仅仅是酒吧的值(这是真的都应该关心的问题,因为那是它是由排序)。

The problem is my comparer is given a type of my class instead of the value of the property/column being sorted by. So if the class is Foo and I'm sorting by Foo.Bar, I get the entire Foo class, not just the value of Bar (which is really all it should be concerned about, since that's what it's sorting by).

如何我知道比较器来比较哪个属性?也许我在这里做得不对,因为这没有任何意义。我希望得到x和y的字符串(属性类型)...

How will my comparer know which property to compare? Maybe I'm doing something wrong here, because this doesn't make any sense. I expected to get a String (the property type) for x and y...

有谁知道如何做到这一点?

Does anyone know how to do this?

的IComparer 的实施会得到整个对象,你需要找出被点击的列,可能是做这样的事情:

Your IComparer implementation will be given the entire object, you need to figure out which column gets clicked, probably by doing something like this:

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

,然后养活到 MyComparer 可能通过修改你的构造函数采取的属性路径。

and then feed that into your MyComparer probably by modifying your constructor to take in the property path.

Col​​umn_Sort 就可以得到属性路径是这样的(我在VB有点生疏,但C#这样做:

In Column_Sort you can get the property path something like this (I'm a little rusty on vb, but c# would do this:

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

,然后养活到您的排序逻辑。

and then feed that into your sorting logic.

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搜索,发现的这个比较器实现,你可以给它用逗号隔开,并与ASC后缀几个属性路径/ DESC是这样的:

You just need to customize your IComparer to support multiple column sorting, I googled and found this comparer implementation that you can feed it several property paths separated by commas and suffixed with ASC/DESC like this:

User.LastName DESC, User.FirstName DESC

我觉得对于多列尽可能UI而言排序的惯例是,你需要有控制按钮举行。因此,子类的ListView类并扎入GridViewColumnHeader点击事件和KeyDown事件知道被点击陆续哪些列,然后使用的IComparer 实施养活成。

I think the convention for multi-column sorting as far as UI is concerned is that you need to have the Ctrl button held. So subclass the ListView class and tie into the GridViewColumnHeader clicked event and the KeyDown event to know which columns were clicked in succession and then use an IComparer implementation to feed that into.