FlexGrid for WPF
データのグループ化(ICollectionView を使用)
基本操作 > グループ化 > データのグループ化(ICollectionView を使用)

FlexGrid supports grouping through IDataCollection interface. This section discusses about grouping in FlexGrid .NET 4.5.2 and .NET 5 versions using DataCollection.

               

FlexGrid は、IDataCollection インタフェースを使用したグループ化をサポートします。PropertyGroupDescription クラスを使用してグループ化のレベルをそれぞれ定義することで、FlexGrid で階層化ビューを作成できます。PropertyGroupDescription オブジェクトを使用すると、データをグループ化するためのプロパティを選択し、ValueConverter を実装してグループ化の際にプロパティ値を使用する方法を決定できます。グリッドのGroupRowPosition プロパティを None に設定すると、グリッドレベルでグループ化を無効にすることもできます。

次の図は、国とアクティブ状態に基づいてグループ化したデータを示します。ユーザーは、グループヘッダーのアイコンをクリックして、グループを折りたたんだり展開することができます(TreeView コントロールを使用する場合)。

Grouping in FlexGrid

次のコード例は、DataCollection を使用して国とアクティブ状態に基づいてグループ化されたデータを示します。また、このコードは製品サンプルのFlexGridSamplesを参考にしてください。

C#
コードのコピー
List<Customer> list = GetCustomerList();
PagedCollectionView view = new PagedCollectionView(list);
using (view.DeferRefresh())
{
  view.GroupDescriptions.Clear();
  view.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
  view.GroupDescriptions.Add(new PropertyGroupDescription("Active"));
}
grid.ItemsSource = view;
メモ: using (view.DeferRefresh()) 文はオプションです。この文を追加すると、すべてのグループが設定されるまでデータソースからの通知が保留になるため、パフォーマンスが向上します。

国のイニシャルに基づいてデータをグループ化するには

国の列でグループ化するだけでなく、FlexGrid ではエンドユーザーのさまざまな要件に応じてグループ化を実装できます。たとえば、データを国の列自体ではなく国のイニシャルでグループ化するという独自のシナリオを考えます。次の図は、国名全体ではなく、国名の最初の文字によって FlexGrid でグループ化されたデータを示しています。

Grouping data by country initials

コードでこのシナリオを実行するには、カスタムクラス CountryInitialConverter を作成する必要があります。このクラスは、IValueConverter インタフェースを実装し、グループ化に使用するために国名全体ではなく国名の最初の文字を返します。さらに、以下のコード例で示すように、MainWindow.xaml.cs でコンバータを設定する必要があります。

class CountryInitialConverter : IValueConverter
{
  public object Convert(object value, Type targetType,
    object parameter,
    System.Globalization.CultureInfo culture)
  {
    return ((string)value)[0].ToString().ToUpper();
  }
  public object ConvertBack(object value, Type targetType,
    object parameter,
    System.Globalization.CultureInfo culture)
  {
    throw new NotImplementedException();
  }
}
List<Customer> list = GetCustomerList();
PagedCollectionView view = new PagedCollectionView(list);
using (view.DeferRefresh())
{
  view.GroupDescriptions.Clear();
  view.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
  view.GroupDescriptions.Add(new PropertyGroupDescription("Active"));
  var gd = view.GroupDescriptions[0] as PropertyGroupDescription;
  gd.Converter = new CountryInitialConverter();
}
grid.ItemsSource = view;
               

グループ行には、その行に対応するグループに関する情報が表示されます。具体的には、グループ化に使用されたプロパティや値、項目数などです。この情報をカスタマイズするには、新しい IValueConverter クラスを作成し、グリッドの GroupHeaderConverter プロパティに割り当てます。たとえば、デフォルトのグループヘッダーコンバータは、次のコードで実装されます。

C#
コードのコピー
// グループキャプションの表示形式を設定するクラス
public class GroupHeaderConverter : IValueConverter
{
  public object Convert(object value,
    Type targetType, object parameter,
    System.Globalization.CultureInfo culture)
  {
    var gr = parameter as GroupRow;
    var group = gr.Group;
    if (group != null && gr != null && targetType == typeof(string))
    {
      var desc = gr.Grid.View.GroupDescriptions[gr.Level] as
                 PropertyGroupDescription;
      return desc != null
        ? string.Format("{0}: {1} ({2:n0} items)",
                 desc.PropertyName, group.Name, group.ItemCount)
        : string.Format("{0} ({1:n0} items)",
                 group.Name, group.ItemCount);
    }
    return value;
  }
  public object ConvertBack(object value, Type targetType,
    object parameter,
    System.Globalization.CultureInfo culture)
  {
    return value;
  }
}
               

FlexGrid は、IDataCollection インタフェースを使用したグループ化をサポートします。PropertyGroupDescription クラスを使用してグループ化のレベルをそれぞれ定義することで、FlexGrid で階層化ビューを作成できます。PropertyGroupDescription オブジェクトを使用すると、データをグループ化するためのプロパティを選択し、ValueConverter を実装してグループ化の際にプロパティ値を使用する方法を決定できます。グリッドのGroupRowPosition プロパティを None に設定すると、グリッドレベルでグループ化を無効にすることもできます

次の図は、国とアクティブ状態に基づいてグループ化したデータを示します。ユーザーは、グループヘッダーのアイコンをクリックして、グループを折りたたんだり展開することができます(TreeView コントロールを使用する場合)。

DataGrouping

次のコード例は、DataCollection を使用して国とアクティブ状態に基づいてグループ化されたデータを示します。また、このコードは製品サンプルのFlexGridExplorerを参考にしてください。

C#
コードのコピー
// Generate FlexGrid data
var data = new ObservableCollection<Customer>();
for (int i = 0; i < 200; i++)
{
    data.Add(new Customer(i));
}
var view = new MyCollectionView(data);
using (view.DeferRefresh())
{
    view.GroupDescriptions.Clear();
    view.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
    view.GroupDescriptions.Add(new PropertyGroupDescription("Active"));
    var gd = view.GroupDescriptions[0] as PropertyGroupDescription;                
}

// bind grids to ListCollectionView
grid.ItemsSource = view;
メモ: using (view.DeferRefresh()) 文はオプションです。この文を追加すると、すべてのグループが設定されるまでデータソースからの通知が保留になるため、パフォーマンスが向上します。

国のイニシャルに基づいてデータをグループ化するには

国の列でグループ化するだけでなく、FlexGrid ではエンドユーザーのさまざまな要件に応じてグループ化を実装できます。たとえば、データを国の列自体ではなく国のイニシャルでグループ化するという独自のシナリオを考えます。次の図は、国名全体ではなく、国名の最初の文字によって FlexGrid でグループ化されたデータを示しています。

コードでこのシナリオを実行するには、カスタムクラス CountryInitialGrouping を作成する必要があります。このクラスは、IValueConverter インタフェースを実装し、グループ化に使用するために国名全体ではなく国名の最初の文字を返します。さらに、以下のコード例で示すように、MainWindow.xaml.cs でコンバータを設定する必要があります。


<code>public void CountryInitialGrouping()
{
    // FlexGridデータを生成します
    var data = new ObservableCollection<Customer>();
    for (int i = 0; i < 200; i++)
    {
        data.Add(new Customer(i));
    }
    var view = new MyCollectionView(data);
    using (view.DeferRefresh())
    {
        view.GroupDescriptions.Clear();
        view.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
        view.GroupDescriptions.Add(new PropertyGroupDescription("Active"));
        var gd = view.GroupDescriptions[0] as PropertyGroupDescription;
        gd.Converter = new CountryInitialConverter();
    }

    //グリッドをListCollectionViewにバインドします
    grid.ItemsSource = view;
C#
コードのコピー
// グループキャプションの表示形式を設定するクラス
public class GroupHeaderConverter : IValueConverter
{
  public object Convert(object value,
    Type targetType, object parameter,
    System.Globalization.CultureInfo culture)
  {
    var gr = parameter as GroupRow;
    var group = gr.Group;
    if (group != null && gr != null && targetType == typeof(string))
    {
      var desc = gr.Grid.View.GroupDescriptions[gr.Level] as
                 PropertyGroupDescription;
      return desc != null
        string.Format("{0}: {1} ({2:n0} items)",
                 desc.PropertyName, group.Name, group.ItemCount)
        : string.Format("{0} ({1:n0} items)",
                 group.Name, group.ItemCount);
    }
    return value;
  }
  public object ConvertBack(object value, Type targetType,
    object parameter,
    System.Globalization.CultureInfo culture)
  {
    return value;
  }
}
関連トピック