2017-04-11 77 views
1

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

Before

我希望我的用户能够通过任意列进行排序,然而,仅仅通过“价值”订货会混淆的组。我希望这些组保持分组状态,同时按指定的列进行排序。

例如,按列“值”进行排序,升序应按每组中的最小“值”对组排序。结果应该是:

After

我已经有了一种处理工作,我怀疑LINQ的可能是有用的在这里,但我似乎无法找到一种方法来排序价值和组名。

回答

0

这是小例子如何分组像你想,你可以改变它,你的列表来自数据库,你可以做同样的像我一样,不要忘记约了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; 
    } 

} 
0

您需要确按以下方式实现分类处理程序(请参阅代码中的注释):

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); 
    } 
}