关于 syncfusion-winforms-grouping
用于实现 Syncfusion Grouping Engine 的技能,该 .NET 框架面向 Windows Forms 应用中的表格数据管理。它涵盖排序、筛选、分层分组、汇总和计算字段,且不依赖 UI 组件。
主要功能
- 01按标准或自定义规则排序
- 02使用逻辑和比较表达式筛选
- 03创建嵌套分组
- 04计算聚合汇总
- 05定义表达式计算字段
适用场景
- 01生成区域销售汇总
- 02查找库存不足的商品
- 03使用计算值分析客户
- 04筛选并分组日期记录
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ syncfusion/ winforms-ui-components-skills --skill syncfusion-winforms-grouping安装后在 Claude Code 中输入/syncfusion-winforms-grouping确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/data-binding.mdexpressions-and-summaries.mdfiltering.mdgetting-started.mdgrouping-data.mdsorting.md详细介绍
实现 Syncfusion 分组引擎
Essential Grouping 是一个 100% 原生的 .NET 数据管理框架,可为表格数据提供排序、分组、筛选和汇总功能,且不依赖任何特定的 UI 组件。它专为 Windows Forms 应用程序设计。
何时使用此技能
在需要以下功能时使用此技能:
- 对数据排序:按一个或多个属性进行排序,使用标准或自定义比较逻辑
- 对数据分组:按属性进行分层分组,创建嵌套组
- 筛选记录:使用代数和逻辑运算符,根据复杂表达式进行筛选
- 汇总数据:执行聚合计算(求和、平均值、最小值、最大值、计数)
- 添加计算字段:使用基于表达式的属性
- 管理表格数据:处理来自任意 IList 数据源的数据(ArrayList、List、BindingList 等)
- 构建数据驱动的应用程序:灵活地组织数据
- 显示分组和汇总信息:不依赖 UI 控件
组件概览
分组引擎使用平衡二叉树作为核心数据结构,以高效执行数据操作。主要优势包括:
- O(Log n) 操作:用于插入、移除和移动操作
- 缓存父级信息:快速查找位置和汇总信息
- 递归分组:支持多层嵌套组
- 表达式支持:用于计算字段和筛选条件
- 平台支持:针对 Windows Forms 应用程序进行了优化
文档与导航指南
入门与安装
📄 阅读: references/getting-started.md
- 安装位置和部署要求
- 创建 Windows Forms 应用程序
- 所需的程序集引用和依赖项
- 设置 Copy Local 属性以进行部署
- 部署方案和 GAC 选项
- Windows Forms 部署所需的 DLL
数据绑定基础
📄 阅读: references/data-binding.md
- 使用公共属性创建自定义对象
- 构建 ArrayList 和 IList 数据源
- 使用 Engine.SetSourceList() 设置数据源
- 遍历 Table.Records 集合
- 使用 Record.GetData() 访问记录数据
- 了解 Engine 和 Table 之间的关系
对数据分组
📄 阅读: references/grouping-data.md
- 使用 TableDescriptor.GroupedColumns 集合
- 通过 Table.TopLevelGroup 访问分组
- 递归遍历 Groups 和 Records
- 按键值检索特定分组
- 了解分组层级模式
- 分组的副作用(自动排序)
- 显示组内的记录
对数据排序
📄 阅读: references/sorting.md
- 将列添加到 TableDescriptor.SortedColumns
- 指定排序方向(Ascending/Descending)
- 使用 IComparer 接口实现自定义排序
- 使用 SortColumnDescriptor.Comparer 属性
- 数值与字符串排序策略
- 多列排序场景
筛选记录
📄 阅读: references/filtering.md
- 使用表达式创建 RecordFilterDescriptor
- 使用 Table.FilteredRecords 集合
- 筛选表达式语法和运算符
- 逻辑运算符(AND、OR、NOT)
- 比较运算符(=、<、>、<=、>=、<>)
- 字符串运算符(LIKE、MATCH、IN、BETWEEN)
- 构建复杂的多条件筛选器
- 清除和更新筛选集合
表达式和汇总
📄 阅读: references/expressions-and-summaries.md
- 为计算字段创建 ExpressionFieldDescriptor
- 使用属性名称编写代数表达式
- 添加到 TableDescriptor.ExpressionFields 集合
- 使用 Record.GetValue() 获取表达式值
- 创建用于聚合的 SummaryDescriptor
- 汇总类型(Int32Aggregate、DoubleAggregate 等)
- 使用 GetSummary() 获取各分组的汇总值
- 代数运算符和求值优先级
- 自定义函数支持和限制
快速入门示例
using System;
using System.Collections;
using Syncfusion.Grouping;
// Define a custom data object
public class SalesRecord
{
public string Product { get; set; }
public string Category { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public SalesRecord(string product, string category, int qty, decimal price)
{
Product = product;
Category = category;
Quantity = qty;
Price = price;
}
}
// Create and populate datasource
ArrayList salesData = new ArrayList();
salesData.Add(new SalesRecord("Laptop", "Electronics", 5, 1200.00m));
salesData.Add(new SalesRecord("Mouse", "Electronics", 25, 15.00m));
salesData.Add(new SalesRecord("Desk", "Furniture", 10, 350.00m));
salesData.Add(new SalesRecord("Chair", "Furniture", 20, 150.00m));
// Create Grouping Engine and set datasource
Engine groupingEngine = new Engine();
groupingEngine.SetSourceList(salesData);
// Group by Category
groupingEngine.TableDescriptor.GroupedColumns.Add("Category");
// Add summary for Quantity
SummaryDescriptor quantitySummary = new SummaryDescriptor(
"TotalQuantity",
"Quantity",
SummaryType.Int32Aggregate
);
groupingEngine.TableDescriptor.Summaries.Add(quantitySummary);
// Iterate through groups and display summaries
foreach (Group group in groupingEngine.Table.TopLevelGroup.Groups)
{
Console.WriteLine($"Category: {group.Name}");
// Get summary value
var summary = group.GetSummary("TotalQuantity") as Int32AggregateSummary;
Console.WriteLine($"Total Items: {summary.Sum}");
// Display records in this group
foreach (Record rec in group.Records)
{
SalesRecord sale = rec.GetData() as SalesRecord;
Console.WriteLine($" {sale.Product}: {sale.Quantity} @ ${sale.Price}");
}
Console.WriteLine();
}
常见模式
模式 1:先筛选后分组的工作流
// 1. Create engine and set datasource
Engine engine = new Engine();
engine.SetSourceList(dataList);
// 2. Apply filter first
RecordFilterDescriptor filter = new RecordFilterDescriptor("[Price] > 100");
engine.TableDescriptor.RecordFilters.Add(filter);
// 3. Then group filtered results
engine.TableDescriptor.GroupedColumns.Add("Category");
// 4. Access filtered and grouped data
foreach (Group group in engine.Table.TopLevelGroup.Groups)
{
// Process each group
}
模式 2:多级分组
// Group by multiple columns for nested hierarchy
engine.TableDescriptor.GroupedColumns.Add("Region");
engine.TableDescriptor.GroupedColumns.Add("Category");
engine.TableDescriptor.GroupedColumns.Add("SubCategory");
// Navigate nested groups recursively
void ProcessGroup(Group group, int level)
{
if (group.Records != null && group.Records.Count > 0)
{
// Terminal group with records
foreach (Record rec in group.Records)
{
// Process record
}
}
else if (group.Groups != null && group.Groups.Count > 0)
{
// Parent group with sub-groups
foreach (Group subGroup in group.Groups)
{
ProcessGroup(subGroup, level + 1);
}
}
}
模式 3:动态表达式字段
// Add calculated column for total value
ExpressionFieldDescriptor totalExpr = new ExpressionFieldDescriptor(
"TotalValue",
"[Quantity] * [Price]"
);
engine.TableDescriptor.ExpressionFields.Add(totalExpr);
// Use expression in filter
RecordFilterDescriptor highValueFilter = new RecordFilterDescriptor(
"[TotalValue] > 1000"
);
engine.TableDescriptor.RecordFilters.Add(highValueFilter);
// Retrieve expression values
foreach (Record rec in engine.Table.FilteredRecords)
{
decimal total = (decimal)rec.GetValue("TotalValue");
Console.WriteLine($"Total: ${total}");
}
模式 4:使用 IComparer 自定义排序
// Implement custom comparer
public class CustomComparer : IComparer
{
public int Compare(object x, object y)
{
// Custom comparison logic
string str1 = x.ToString();
string str2 = y.ToString();
// Example: Sort by length first, then alphabetically
int lengthCompare = str1.Length.CompareTo(str2.Length);
return lengthCompare != 0 ? lengthCompare : str1.CompareTo(str2);
}
}
// Apply custom sort
engine.TableDescriptor.SortedColumns.Add("Product");
engine.TableDescriptor.SortedColumns["Product"].Comparer = new CustomComparer();
关键属性和集合
Engine 类
| 属性 | 描述 |
|---|---|
Table | 获取包含记录和分组的 Table 对象 |
TableDescriptor | 获取架构信息和配置 |
SetSourceList(IList) | 设置引擎的数据源 |
TableDescriptor 属性
| 属性 | 描述 |
|---|---|
GroupedColumns | 要分组的属性集合 |
SortedColumns | 要排序的属性集合 |
RecordFilters | 筛选条件集合 |
Summaries | 汇总计算集合 |
ExpressionFields | 计算字段集合 |
Table 属性
| 属性 | 描述 |
|---|---|
Records | 表中的所有记录 |
FilteredRecords | 应用筛选条件后的记录 |
TopLevelGroup | 用于分层访问的根分组 |
Group 类
| 属性 | 描述 |
|---|---|
Groups | 子分组(用于父分组) |
Records | 此分组中的记录(用于末级分组) |
Name | 分组键/名称 |
GetSummary(string) | 按名称获取汇总值 |
Record 类
| 方法 | 描述 |
|---|---|
GetData() | 返回底层数据对象 |
GetValue(string) | 按名称获取属性值或表达式值 |
常见用例
用例 1:按地区和产品生成销售报告
// Group sales by region, then product category
engine.TableDescriptor.GroupedColumns.Add("Region");
engine.TableDescriptor.GroupedColumns.Add("ProductCategory");
// Add sales summaries
engine.TableDescriptor.Summaries.Add(
new SummaryDescriptor("TotalSales", "SalesAmount", SummaryType.DoubleAggregate)
);
engine.TableDescriptor.Summaries.Add(
new SummaryDescriptor("OrderCount", "OrderID", SummaryType.Count)
);
用例 2:筛选低库存商品
// Filter for items below reorder level
RecordFilterDescriptor lowStock = new RecordFilterDescriptor(
"[StockLevel] < [ReorderLevel] AND [Active] = 1"
);
engine.TableDescriptor.RecordFilters.Add(lowStock);
// Sort by urgency (stock level ascending)
engine.TableDescriptor.SortedColumns.Add("StockLevel", ListSortDirection.Ascending);
用例 3:使用计算字段分析客户
// Add expression for customer value
ExpressionFieldDescriptor customerValue = new ExpressionFieldDescriptor(
"CustomerValue",
"[TotalOrders] * [AverageOrderAmount]"
);
engine.TableDescriptor.ExpressionFields.Add(customerValue);
// Filter for high-value customers
RecordFilterDescriptor premiumCustomers = new RecordFilterDescriptor(
"[CustomerValue] > 10000"
);
engine.TableDescriptor.RecordFilters.Add(premiumCustomers);
// Group by customer tier
engine.TableDescriptor.GroupedColumns.Add("Tier");
用例 4:基于时间的数据分析
// Filter for date range using BETWEEN operator
RecordFilterDescriptor dateRange = new RecordFilterDescriptor(
"[OrderDate] BETWEEN {1/1/2024, 12/31/2024}"
);
engine.TableDescriptor.RecordFilters.Add(dateRange);
// Group by month (requires calculated field)
ExpressionFieldDescriptor monthField = new ExpressionFieldDescriptor(
"OrderMonth",
"Month([OrderDate])"
);
engine.TableDescriptor.ExpressionFields.Add(monthField);
engine.TableDescriptor.GroupedColumns.Add("OrderMonth");
边缘情况和故障排除
空分组
筛选后分组可能为空。迭代前请始终检查 Records.Count。
表达式中的类型不匹配
属性值必须与运算类型匹配:
- 数值比较使用
= - 字符串比较使用
LIKE或MATCH - 使用适当的汇总类型(Int32Aggregate 与 DoubleAggregate)
递归导航
递归导航分组时,请检查 group.Groups 或 group.Records 是否已填充。每个层级中只有其中一个会包含项。
筛选表达式语法
- 属性名称必须用方括号括起来:
[PropertyName] - 字符串字面量必须用单引号括起来:
'value' - IN 运算符列表中的空格有意义:
{value1,value2},而不是{value1, value2}
内存管理
Grouping Engine 会维护内部数据结构。完成后调用 Dispose() 以释放资源。
最佳实践
- 配置前设置数据源:添加分组、排序或筛选条件前,先调用
SetSourceList() - 使用 FilteredRecords 获取筛选后的数据:筛选条件生效时,访问
Table.FilteredRecords,而非Table.Records - 选择合适的汇总类型:使汇总类型与属性的数据类型(Int32、Double、Boolean 等)相匹配
- 优化表达式:复杂表达式会影响性能;尽可能保持简单
- 处理 null 值:使用
GetData()访问记录数据时,检查是否为 null - 正确释放资源:不再需要 Engine 对象时,将其释放
- 测试筛选表达式:部署前验证筛选语法,避免运行时错误
平台特定说明
Windows Forms
- 分组引擎可独立运行,也可与 GridGroupingControl 配合使用
- 无需 UI 依赖项
- 针对桌面应用场景进行了优化
后续步骤
- 阅读 getting-started.md,了解安装和设置
- 查看 data-binding.md,了解数据源要求
- 根据需要,查阅相应的参考文件以了解具体功能
- 查看各参考文件中的代码示例,了解实现细节
评论
支持 Markdown