2017-04-11 19 views
1

データベースクエリによって作成されたWPF DataGridがあります。最初の結果がまとめられ、SQLでソートされていますWPF DataGridをグループ内の値でソートします。

Before

しかし私は、単に「バリュー」で注文すると、グループをミックスします、私のユーザーは任意の列でソートできるようにしたいと思います。指定した列でソートされている間、グループをグループ化したままにしておきたい。

たとえば、列「値」を昇順に並べ替えると、グループを各グループ内の最小「値」でソートする必要があります。結果は次のようになります。

After

私はすでにソートハンドラの作業を持っていると私は、LINQのは、ここで役に立つかもしれないが、私は価値とグループ名の両方をソートする方法を見つけるように見えることはできませんと思われます。

答えて

0

これは、あなたが望むように、あなたはそれを変更することができますどのようにグループの小さな一例である、あなたのリストは、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; 
    } 

} 
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); 
    } 
} 
関連する問題