按组中的值对WPF DataGrid进行排序 [英] Sort a WPF DataGrid by a value within a group
问题描述
我有一个WPF DataGrid,它由数据库查询填充.初始结果在SQL中进行分组和排序:
I have a WPF DataGrid which is populated by a database query. The initial results are grouped and sorted in SQL:
我希望我的用户能够按任意列进行排序,但是仅按值"排序将使各组混淆.我希望这些组保持分组状态,同时按指定的列进行排序.
I'd like my users to be able to sort by arbitrary columns, however simply ordering by "Value" will mix up the groups. I want the groups to remain grouped, while being sorted by the specified column.
例如,按升序按值"列排序,应按每个组中的最小值"对组进行排序.结果应该是:
For example, sorting by the column "Value", ascending, should sort the Groups by their minimum "Value" within each group. The result should be:
我已经有一个排序处理程序在工作,我怀疑Linq在这里可能有用,但是我似乎找不到找到对Value和GroupName进行排序的方法.
I've already got a sort handler working and I suspect that Linq might be useful here, but I can't seem to find a way to sort both Value and GroupName.
推荐答案
您实际上需要以以下方式实现排序处理程序(请参见代码中的注释):
You need to indeed implement sorting handler, in the following way (see the comments in code):
private void OnSorting(object sender, DataGridSortingEventArgs e) {
if (e.Column.SortMemberPath == "Value") {
// get view
var source = (ListCollectionView) CollectionViewSource.GetDefaultView(this.Items);
// manually change sort direction to the next value
// so null > ascending > descending > back to null
var sort = e.Column.SortDirection;
if (sort == null)
sort = ListSortDirection.Ascending;
else if (sort == ListSortDirection.Ascending)
sort = ListSortDirection.Descending;
else
sort = null;
if (sort != null) {
// first figure out correct group ordering
var sortedGroups = dataGrid.ItemsSource.OfType<Item>()
.GroupBy(c => c.GroupName)
.Select(c => new {GroupName = c.Key, MinValue = c.Min(r => r.Value)})
.OrderBy(c => c.MinValue)
.Select(c => c.GroupName)
.ToArray();
// now set collection view custom sort to out comparer
source.CustomSort = new ItemComparer(sortedGroups, sort == ListSortDirection.Ascending);
}
else {
// otherwise remove custom sort and sort as usual
source.CustomSort = null;
}
e.Column.SortDirection = sort;
e.Handled = true;
}
}
public class ItemComparer : IComparer {
private readonly string[] _sortedGroups;
private readonly bool _asc;
public ItemComparer(string[] sortedGroups, bool asc) {
_sortedGroups = sortedGroups;
_asc = asc;
}
public int Compare(object ox, object oy) {
var x = (Item) ox;
var y = (Item) oy;
if (x.GroupName == y.GroupName) {
// if group names are the same - sort as usual, by Value
return x.Value.CompareTo(y.Value) * (_asc ? 1 : -1);
}
// otherwise - sort by group name using the order we already figured out at previous step
return (Array.IndexOf(_sortedGroups, x.GroupName) - Array.IndexOf(_sortedGroups, y.GroupName)) * (_asc ? 1 : -1);
}
}
这篇关于按组中的值对WPF DataGrid进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!