mcpField
S
syncfusion-wpf-grouping

syncfusion-wpf-grouping

github.com/syncfusionデータ・データベース5127 回インストール2 週間前に更新
リポジトリ

syncfusion-wpf-grouping について

このスキルは、UI コンポーネントに依存せず表形式データを整理・操作する .NET ライブラリ、Syncfusion Essential Grouping を解説します。グループ化ビュー、レポート、処理パイプラインを作る開発者向けで、階層グループ、式によるフィルター、集計に対応します。

主な機能

  1. 01レコードの階層グループ化
  2. 02標準ソートとカスタムソート
  3. 03式によるレコードフィルター
  4. 04グループ単位の集計
  5. 05式による計算列の追加
  6. 06効率的な挿入・削除・移動

活用シーン

  1. 01売上データを地域や月でまとめてレポート化
  2. 02部門ごとの給与集計
  3. 03在庫のフィルタリングと分析
  4. 04エクスポート用の階層データ準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/syncfusion/wpf-ui-components-skills --skill syncfusion-wpf-grouping

インストール後、Claude Code で/syncfusion-wpf-groupingを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
data-binding.md
filtering.md
getting-started.md
grouping-operations.md
sorting.md
summaries-and-expressions.md

詳細

WPF 向け Syncfusion Essential Grouping の実装

Syncfusion Essential Grouping は、特定の UI コンポーネントに依存せずに表形式の情報を管理、操作できる、100%ネイティブな .NET データテクノロジーライブラリです。このフレームワークは、C#、VB.NET、マネージド C++ など、あらゆる .NET 環境で使用できるため、視覚的なコントロールに依存せずに高度なデータ整理機能が必要なシナリオに最適です。

このスキルを使用する場面

次のような場合は、Essential Grouping を使用してください。

  • 特定の UI コントロールにバインドせずに、表形式のデータを整理、分析する
  • 1 つ以上のプロパティでデータを階層的にグループ化する(例:月別の売上、部署別の従業員)
  • IComparer の実装によるカスタム並べ替えロジックなど、複雑な並べ替えを適用する
  • プロパティ、論理演算子、特殊演算子(LIKE、MATCH、IN、BETWEEN)を使った式に基づいてレコードをフィルターする
  • グループレベルで集計(合計、平均、最小、最大、件数)を計算する
  • 代数式を使った式フィールドで計算列を追加する
  • 項目がパブリックプロパティを持つ IList データソースを扱う
  • 二分木データ構造(挿入/削除/移動に Log2(n) 回の操作)を使用して、大規模なデータセットを効率的に処理する
  • サブグループと再帰的なデータ構造で、ネストされたグループ化を作成する

GroupingEngine は、異なる UI フレームワーク間で機能するデータ操作機能が必要な場合や、データ処理、レポート作成、サーバー側の処理など、UI を使用しないシナリオで特に強力です。

基本概念

アーキテクチャの概要

Essential Grouping は、配列ではなく、コアデータ構造として平衡二分木を使用します。二分木では、親ブランチに子の情報をキャッシュできるため、次のことが可能になります。

  • キャッシュされた情報によるすばやい位置検索
  • 親ブランチにキャッシュされた高速な集計計算
  • Log2(n) 回の操作で済む効率的な挿入/削除/移動(ArrayList の場合は O(n))
主なコンポーネント

Engine:データ操作パイプライン全体を管理する、メインの GroupingEngine オブジェクト

TableDescriptor:次のキーコレクションを含むスキーマ情報の保持オブジェクト:

  • GroupedColumns - グループ化するプロパティ
  • SortedColumns - 並べ替えるプロパティ
  • Summaries - 実行する集計計算
  • RecordFilters - 適用するフィルター条件
  • ExpressionFields - 追加する計算列

Table:次のコレクションを含む実データの保持オブジェクト:

  • Records - データソースのすべてのレコード
  • FilteredRecords - フィルター適用後のレコード
  • TopLevelGroup - 階層データにアクセスするためのルートグループ

グループとレコード:次のような再帰的構造:

  • グループには、Groups(サブグループ)または Records(末端データ)のどちらかが含まれます
  • TopLevelGroup を通じて階層的に移動します

ドキュメントとナビゲーションガイド

はじめにとセットアップ

📄 参照: references/getting-started.md

  • 前提条件と互換性(.NET 2.0 - 4.6、VS 2015 以降)
  • インストールと必要なアセンブリ
  • 配置設定(Copy Local、ライセンス)
  • 最初の GroupingEngine アプリケーションの作成
  • 基本的なプロジェクトのセットアップと名前空間のインポート
データバインディングと反復処理

📄 参照: references/data-binding.md

  • IList データソースの要件
  • パブリックプロパティを持つカスタムオブジェクトクラスの作成
  • ArrayList データソースの構築
  • SetSourceList によるデータソースの設定
  • Table.Records を使ったレコードの反復処理
  • GetData() メソッドと型キャスト
グループ化操作

📄 参照: references/grouping-operations.md

  • GroupedColumns コレクションへのプロパティの追加
  • TableDescriptor コレクションについて
  • TopLevelGroup へのアクセス
  • 再帰的なグループ構造のナビゲーション
  • 値による特定のグループの取得
  • Group.Groups コレクションと Group.Records コレクション
並べ替え(標準およびカスタム)

📄 参照: references/sorting.md

  • SortedColumns コレクションへのプロパティの追加
  • 並べ替え方向の指定(ListSortDirection)
  • SortedColumns.Add メソッドのオーバーロード
  • IComparer を使用したカスタム並べ替えの実装
  • カスタム比較クラスの作成
  • 比較クラスの SortColumnDescriptor への割り当て
式によるフィルタリング

📄 参照: references/filtering.md

  • RecordFilterDescriptor オブジェクトの作成
  • 角括弧 [] を使用したフィルター式の構文
  • 文字列演算子:LIKE、MATCH
  • 数値比較:=、<、>、<=、>=、<>
  • OR、AND を使用した複雑な式
  • FilteredRecords コレクションの使用
集計と式フィールド

📄 参照: references/summaries-and-expressions.md

  • SummaryDescriptor オブジェクトの作成
  • SummaryType 列挙型(Int32Aggregate、DoubleAggregate など)
  • GetSummary による集計値の取得
  • ExpressionFieldDescriptor による式フィールドの追加
  • 代数式の構文
  • 特殊演算子:MATCH、LIKE、IN、BETWEEN
  • 式でのカスタム関数

クイックスタート

基本的な GroupingEngine の設定
using System;
using System.Collections;
using Syncfusion.Grouping;

namespace GroupingSample
{
    class Program
    {
        static void Main(string[] args)
        {
            // 1. Create your data source (IList with objects having public properties)
            ArrayList list = new ArrayList();
            list.Add(new Employee { Name = "John", Department = "Sales", Salary = 50000 });
            list.Add(new Employee { Name = "Jane", Department = "IT", Salary = 65000 });
            list.Add(new Employee { Name = "Bob", Department = "Sales", Salary = 55000 });
            list.Add(new Employee { Name = "Alice", Department = "IT", Salary = 70000 });

            // 2. Create GroupingEngine and set data source
            Engine groupingEngine = new Engine();
            groupingEngine.SetSourceList(list);

            // 3. Access data through Table.Records
            Console.WriteLine("All Records:");
            foreach (Record rec in groupingEngine.Table.Records)
            {
                Employee emp = rec.GetData() as Employee;
                if (emp != null)
                {
                    Console.WriteLine($"{emp.Name}, {emp.Department}, {emp.Salary}");
                }
            }

            // 4. Apply grouping
            groupingEngine.TableDescriptor.GroupedColumns.Add("Department");

            // 5. Navigate groups
            Console.WriteLine("\nGrouped by Department:");
            ShowRecordsUnderGroup(groupingEngine.Table.TopLevelGroup);

            Console.ReadLine();
        }

        static void ShowRecordsUnderGroup(Group g)
        {
            if (g.Records != null && g.Records.Count > 0)
            {
                // Terminal group - display records
                foreach (Record rec in g.Records)
                {
                    Employee emp = rec.GetData() as Employee;
                    if (emp != null)
                    {
                        Console.WriteLine($"  {emp.Name}, {emp.Department}, {emp.Salary}");
                    }
                }
            }
            else if (g.Groups != null && g.Groups.Count > 0)
            {
                // Has sub-groups - recurse
                foreach (Group subGroup in g.Groups)
                {
                    Console.WriteLine($"Group: {subGroup.Name}");
                    ShowRecordsUnderGroup(subGroup);
                }
            }
        }
    }

    public class Employee
    {
        public string Name { get; set; }
        public string Department { get; set; }
        public int Salary { get; set; }
    }
}

よく使われるパターン

パターン 1:グループ化して集計値を計算する
// Group by department
groupingEngine.TableDescriptor.GroupedColumns.Add("Department");

// Add summary for salary
SummaryDescriptor salarySum = new SummaryDescriptor(
    "DeptSalaryTotal", 
    "Salary", 
    SummaryType.Int32Aggregate
);
groupingEngine.TableDescriptor.Summaries.Add(salarySum);

// Get summary for a specific group
Group itGroup = groupingEngine.Table.TopLevelGroup.Groups["IT"];
ISummary summary = itGroup.GetSummary("DeptSalaryTotal");
Int32AggregateSummary aggSummary = (Int32AggregateSummary)summary;

Console.WriteLine($"IT Department Total: {aggSummary.Sum}");
Console.WriteLine($"IT Department Average: {aggSummary.Average}");
パターン 2:データをフィルタリングして並べ替える
// Sort by salary descending
SortColumnDescriptor sortDesc = new SortColumnDescriptor(
    "Salary", 
    ListSortDirection.Descending
);
groupingEngine.TableDescriptor.SortedColumns.Add(sortDesc);

// Filter for salaries over 60000
RecordFilterDescriptor filter = new RecordFilterDescriptor("[Salary] > 60000");
groupingEngine.TableDescriptor.RecordFilters.Add(filter);

// Access filtered records
foreach (Record rec in groupingEngine.Table.FilteredRecords)
{
    Employee emp = rec.GetData() as Employee;
    Console.WriteLine($"{emp.Name}: {emp.Salary}");
}
パターン 3:式フィールド(計算列)を追加する
// Add a calculated bonus field (10% of salary)
ExpressionFieldDescriptor bonusField = new ExpressionFieldDescriptor(
    "Bonus", 
    "[Salary] * 0.10"
);
groupingEngine.TableDescriptor.ExpressionFields.Add(bonusField);

// Access the calculated value
foreach (Record rec in groupingEngine.Table.Records)
{
    Employee emp = rec.GetData() as Employee;
    object bonusValue = rec.GetValue("Bonus");
    Console.WriteLine($"{emp.Name}: Salary={emp.Salary}, Bonus={bonusValue}");
}
パターン 4:IComparer によるカスタム並べ替え
// Custom comparer for case-insensitive name sorting
public class NameComparer : IComparer
{
    public int Compare(object x, object y)
    {
        if (x == null && y == null) return 0;
        if (x == null) return -1;
        if (y == null) return 1;
        
        return string.Compare(
            x.ToString(), 
            y.ToString(), 
            StringComparison.OrdinalIgnoreCase
        );
    }
}

// Apply custom comparer
NameComparer comparer = new NameComparer();
groupingEngine.TableDescriptor.SortedColumns.Add("Name");
groupingEngine.TableDescriptor.SortedColumns["Name"].Comparer = comparer;
パターン 5:ネストされたグループ化(複数レベル)
// Group by Department, then by Salary range
groupingEngine.TableDescriptor.GroupedColumns.Add("Department");
groupingEngine.TableDescriptor.GroupedColumns.Add("SalaryRange");

// Navigate nested groups
foreach (Group deptGroup in groupingEngine.Table.TopLevelGroup.Groups)
{
    Console.WriteLine($"Department: {deptGroup.Name}");
    
    foreach (Group salaryGroup in deptGroup.Groups)
    {
        Console.WriteLine($"  Salary Range: {salaryGroup.Name}");
        
        foreach (Record rec in salaryGroup.Records)
        {
            Employee emp = rec.GetData() as Employee;
            Console.WriteLine($"    {emp.Name}: {emp.Salary}");
        }
    }
}

主なプロパティとコレクション

エンジンのプロパティ
  • Table - 実際のデータを保持し、Records、FilteredRecords、TopLevelGroup へのアクセスを提供します
  • TableDescriptor - グループ化、並べ替え、フィルタリング、集計の各コレクションを含むスキーマ情報です
TableDescriptor のコレクション
  • GroupedColumns - グループ化するプロパティ(複数追加すると階層的にグループ化されます)
  • SortedColumns - カスタム比較クラスを指定して並べ替えるプロパティ
  • RecordFilters - 式の構文を使用したフィルター条件
  • Summaries - 集計計算(Sum、Average、Min、Max、Count など)
  • ExpressionFields - 代数式を使用した計算列
グループのプロパティ
  • Groups - 子グループのコレクション(終端グループでない場合)
  • Records - レコードのコレクション(終端グループの場合)
  • Name - このグループのグループ化値
  • GetSummary(string name) - このグループの集計値を取得します
レコードのメソッド
  • GetData() - 基になるデータオブジェクトを返します
  • GetValue(string propertyName) - プロパティまたは式フィールドの値を取得します

一般的なユースケース

  1. 売上レポート:地域や月ごとに売上をグループ化し、合計と平均を計算して、高額注文をフィルタリングします
  2. 従業員管理:部署や役職ごとにグループ化し、給与で並べ替えて、給与計算の集計値を算出します
  3. 在庫分析:カテゴリごとに商品をグループ化し、在庫数をフィルタリングして、金額の集計値を算出します
  4. データエクスポートの準備:レポートやその他の形式にエクスポートする前に、データを階層的に整理します
  5. サーバー側のデータ処理:UI に依存せずにサーバー上でデータを操作します
  6. 複数フレームワーク対応アプリケーション:WPF、WinForms、ASP.NET アプリケーション間でデータロジックを共有します
  7. カスタムレポート生成ツール:グループ化と集計を含むレポートデータ構造を構築します
  8. データ検証パイプライン:検証と品質チェックのためにデータをフィルタリングしてグループ化します

必要なアセンブリ

Essential Grouping を使用するアプリケーションをデプロイする際は、次のアセンブリがアプリケーションフォルダーにコピーされていることを確認してください。

  • Syncfusion.Grouping.Base.dll
  • Syncfusion.Shared.Base.dll
  • Syncfusion.Shared.Wpf.dll

コメント