我有一個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);
}
}