我有一个WPF DataGrid,它由数据库查询填充。初步结果进行分组和分类在SQL:对组中的值对WPF DataGrid排序
我希望我的用户能够通过任意列进行排序,然而,仅仅通过“价值”订货会混淆的组。我希望这些组保持分组状态,同时按指定的列进行排序。
例如,按列“值”进行排序,升序应按每组中的最小“值”对组排序。结果应该是:
我已经有了一种处理工作,我怀疑LINQ的可能是有用的在这里,但我似乎无法找到一种方法来排序价值和组名。
我有一个WPF DataGrid,它由数据库查询填充。初步结果进行分组和分类在SQL:对组中的值对WPF DataGrid排序
我希望我的用户能够通过任意列进行排序,然而,仅仅通过“价值”订货会混淆的组。我希望这些组保持分组状态,同时按指定的列进行排序。
例如,按列“值”进行排序,升序应按每组中的最小“值”对组排序。结果应该是:
我已经有了一种处理工作,我怀疑LINQ的可能是有用的在这里,但我似乎无法找到一种方法来排序价值和组名。
这是小例子如何分组像你想,你可以改变它,你的列表来自数据库,你可以做同样的像我一样,不要忘记约了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;
}
}
您需要确按以下方式实现分类处理程序(请参阅代码中的注释):
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);
}
}