我有一个由数据库查询填充的WPF DataGrid。初始结果在SQL中进行分组和排序:

我希望我的用户能够根据任意的列进行排序,但是简单地按"Value“排序就会混淆这些组。我希望组保持分组,同时按指定的列进行排序。
例如,按列"Value“进行排序(升序),应该按照每个组内的最小”值“对组进行排序。其结果应该是:

我已经有了一个排序处理程序,我怀疑Linq在这里可能很有用,但是我似乎找不到一种方法来对值和GroupName进行排序。
发布于 2017-04-11 08:03:00
这是一个很小的例子,如何按需要分组,您可以更改它,您的列表来自db,您可以像我一样做同样的事情,不要忘记IComparable。
static void Main(string[] args)
{
List<MyClass> inputlist = new List<MyClass>();
inputlist.Add(new MyClass { GroupName = "A", Value = 10 });
inputlist.Add(new MyClass { GroupName = "A", Value = 15 });
inputlist.Add(new MyClass { GroupName = "A", Value = 20 });
inputlist.Add(new MyClass { GroupName = "B", Value = 1 });
inputlist.Add(new MyClass { GroupName = "B", Value = 10 });
inputlist.Add(new MyClass { GroupName = "B", Value = 15 });
inputlist.Add(new MyClass { GroupName = "C", Value = 5 });
inputlist.Add(new MyClass { GroupName = "C", Value = 10 });
inputlist.Add(new MyClass { GroupName = "C", Value = 15 });
List<MyClass> outputlist = new List<MyClass>();
foreach (var item in
inputlist.GroupBy(x => x.GroupName).Select(x => new MyClass
{
GroupName = x.First().GroupName,
Value = x.Min().Value
}).ToList().OrderBy(x => x.Value))
{
outputlist.AddRange(inputlist.Where(x => x.GroupName == item.GroupName));
}
foreach (var item in outputlist)
{
Console.WriteLine(item.GroupName + " " + item.Value);
}
Console.ReadLine();
}
}
public class MyClass : IComparable
{
public string GroupName { get; set; }
public int Value { get; set; }
public int CompareTo(object value)
{
int val = (int)Value;
if (this.Value > val) return -1;
if (this.Value == val) return 0;
return 1;
}
}发布于 2017-04-11 08:14:13
您确实需要以以下方式实现排序处理程序(请参阅代码中的注释):
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);
}
}https://stackoverflow.com/questions/43338043
复制相似问题