9.3 KiB
Epic 2 Details: PropertyGrid - Auto-Generated Configuration UI
Epic Goal
实现 PropertyGrid 控件,这是控件库的核心价值所在。该控件能够从数据模型自动生成属性编辑 UI,支持 string, int, double, bool, enum, DateTime 六种基础类型,以及属性分组、只读属性等功能。Epic 完成后,上位机和 AI 应用开发者可以快速构建配置界面,无需手写大量 XAML。该 Epic 在开发过程中会产出必要的布局控件(如 TwoColumnLayout)和工具类。
Story 2.1: 实现 2xN Layout 布局控件
As a 控件库开发者, I want 创建一个专用的 2xN Layout 布局控件(左侧标签,右侧编辑器), so that PropertyGrid 可以使用统一的布局来呈现属性列表,且这个布局控件可以复用到其他需要"标签-值"配对的场景。
Acceptance Criteria
-
在
Penguin.AvaloniaUI/Layouts/下创建TwoColumnLayout.cs控件类:- 继承自
Panel或使用Grid作为基础 - 支持添加多行,每行包含左侧标签(Label)和右侧内容(Content)
- 继承自
-
提供简单的 API 来添加行:
- 可以通过 Items 集合添加行
- 每个 Item 包含 Label(string)和 Content(Control)
-
布局行为:
- 左列(标签列)宽度固定或自适应最长标签的宽度
- 右列(内容列)占据剩余空间
- 行与行之间有合适的垂直间距(如 8px)
- 标签垂直对齐到内容控件的中心或顶部
-
响应主题系统:
- 标签文本颜色使用
TextSecondary - 背景色透明或使用
Surface
- 标签文本颜色使用
-
在 Example 中创建测试页面,演示 TwoColumnLayout 的使用:
- 至少 5 行测试数据
- 包含不同类型的右侧内容(TextBox, CheckBox, ComboBox)
-
布局在窗口缩放时应正确响应,不出现重叠或错位
Story 2.2: 实现基础属性编辑器控件
As a 控件库开发者, I want 为 PropertyGrid 支持的 6 种属性类型创建或选择合适的编辑器控件, so that PropertyGrid 可以根据属性类型自动选择正确的编辑器。
Acceptance Criteria
-
为以下属性类型选择或创建编辑器控件:
- string: 使用 Avalonia 的
TextBox - int/double: 使用 Avalonia 的
NumericUpDown(如果 Semi 或 Avalonia 提供)或自定义数字输入框 - bool: 使用 Avalonia 的
CheckBox - enum: 使用 Avalonia 的
ComboBox,Items 为枚举值列表 - DateTime: 使用 Avalonia 的
DatePicker和TimePicker(或组合控件)
- string: 使用 Avalonia 的
-
所有编辑器控件应响应主题系统,使用语义化颜色
-
编辑器控件应支持基础的数据绑定:
- 双向绑定(TwoWay Binding)
- 支持
INotifyPropertyChanged机制
-
在 Example 中创建测试页面,演示所有 6 种编辑器:
- 每种编辑器独立展示
- 显示当前绑定的值(使用 TextBlock)
- 修改编辑器后,绑定的值应自动更新
-
编辑器控件应具备基础的验证提示能力:
- 依赖 Avalonia 的内置验证机制(如 DataValidationErrors)
- 验证失败时显示红色边框或错误图标
Story 2.3: 实现 PropertyGrid 核心逻辑和数据模型
As a 控件库开发者, I want 定义 PropertyGrid 的数据模型和核心逻辑,支持从对象反射属性信息, so that PropertyGrid 可以自动生成属性列表,为后续的 UI 呈现做好准备。
Acceptance Criteria
-
在
Penguin.AvaloniaUI/Controls/PropertyGrid/下创建以下类:PropertyGrid.cs: PropertyGrid 主控件类PropertyItem.cs: 表示单个属性的数据模型,包含:- Name(属性名称)
- Value(属性值)
- Type(属性类型)
- IsReadOnly(是否只读)
- Category(分组类别,可选)
- Description(描述,可选)
-
PropertyGrid 提供
SelectedObject属性(依赖属性):- 接受任意对象
- 当 SelectedObject 变化时,自动通过反射解析对象的属性
-
反射逻辑:
- 获取对象的所有 public 属性
- 过滤掉不应显示的属性(如索引器、只写属性)
- 支持通过 Attribute 控制属性的显示(可选,如
[Browsable(false)])
-
将反射得到的属性转换为
PropertyItem集合:- 存储在 PropertyGrid 的内部集合中
- 支持属性变化通知(使用 ReactiveUI 或 INotifyPropertyChanged)
-
创建单元测试,验证反射逻辑:
- 测试包含 6 种基础类型的测试对象
- 验证属性数量、名称、类型正确解析
- 验证只读属性标记正确识别
-
在 Example 中创建测试页面,验证数据模型:
- 定义一个包含 6 种类型属性的测试类
- 将测试对象赋值给 PropertyGrid.SelectedObject
- 使用调试输出或 ListBox 显示解析出的 PropertyItem 列表(暂时不渲染为编辑器)
Story 2.4: 实现 PropertyGrid UI 呈现和属性编辑
As a PropertyGrid 的用户(开发者), I want PropertyGrid 能够自动将属性列表渲染为可编辑的 UI, so that 我可以直接使用 PropertyGrid 控件,无需手动编写属性编辑界面。
Acceptance Criteria
-
PropertyGrid 使用 TwoColumnLayout 呈现属性列表:
- 左列显示属性名称(PropertyItem.Name)
- 右列根据属性类型显示对应的编辑器控件
-
属性类型到编辑器的映射逻辑:
- string → TextBox
- int/double → NumericUpDown
- bool → CheckBox
- enum → ComboBox(自动填充枚举值)
- DateTime → DatePicker/TimePicker
-
编辑器控件与属性值双向绑定:
- 修改编辑器时,PropertyItem.Value 自动更新
- PropertyItem.Value 变化时,编辑器自动刷新(如果 SelectedObject 外部修改)
-
只读属性的处理:
- 如果 PropertyItem.IsReadOnly = true,编辑器应禁用(IsEnabled = false)或显示为只读文本
-
在 Example 中创建完整的 PropertyGrid 演示页面:
- 定义一个包含所有 6 种类型的配置类(如
DemoSettings) - 使用 PropertyGrid 绑定到 DemoSettings 实例
- 在页面底部显示当前配置对象的 JSON 或字符串表示,验证属性编辑生效
- 定义一个包含所有 6 种类型的配置类(如
-
PropertyGrid 应响应主题切换,所有编辑器控件使用主题颜色
-
PropertyGrid 的默认宽度应至少 400px,高度自适应内容(或支持滚动)
Story 2.5: 实现属性分组功能
As a PropertyGrid 的用户(开发者), I want PropertyGrid 支持将属性按类别分组显示, so that 当属性数量较多时,配置界面更清晰易读。
Acceptance Criteria
-
PropertyItem 支持 Category 属性(字符串):
- 如果未指定 Category,默认分组为 "General" 或不分组
-
支持通过 Attribute 在数据模型上标记分组:
- 例如使用
[Category("Network")]标记属性 - 反射逻辑自动读取 Category Attribute
- 例如使用
-
PropertyGrid 按 Category 对 PropertyItem 进行分组:
- 相同 Category 的属性显示在一起
- 分组之间有视觉分隔(如分隔线或分组标题)
-
分组标题的呈现:
- 使用稍大的字体或加粗显示分组名称
- 分组标题使用
TextPrimary颜色 - 分组标题上方有一定的间距(如 16px)
-
支持可选的分组折叠功能(可选,MVP 可以暂时不实现折叠):
- 如果时间允许,分组可以展开/折叠
- 默认所有分组展开
-
在 Example 中扩展演示页面:
- DemoSettings 类的属性使用
[Category]标记,分为至少 2 个分组(如 "General"、"Advanced") - PropertyGrid 正确显示分组
- 验证分组标题和属性的视觉层次清晰
- DemoSettings 类的属性使用
Story 2.6: PropertyGrid 集成测试和优化
As a 控件库开发者, I want 对 PropertyGrid 进行全面测试和性能优化, so that 确保 PropertyGrid 在真实场景下稳定可用,并满足性能要求(50 属性 < 200ms)。
Acceptance Criteria
-
创建综合测试类,包含 50 个属性,覆盖所有支持的类型和分组
-
在 Example 中使用该测试类验证 PropertyGrid:
- PropertyGrid 正确渲染所有 50 个属性
- UI 生成时间 < 200ms(符合 NFR5)
- 所有编辑器可正常交互,值绑定正确
-
测试边缘情况:
- SelectedObject 为 null 时,PropertyGrid 显示空状态或提示信息
- 对象属性在运行时变化时,PropertyGrid 能够正确响应(如果支持动态刷新)
- 只读属性不能编辑
-
主题切换测试:
- 在浅色和暗色主题下,PropertyGrid 的视觉呈现正确
- 主题切换时,PropertyGrid 无闪烁或错位
-
性能优化(如果需要):
- 如果初始加载超过 200ms,使用虚拟化或延迟加载优化
- 如果属性数量超过 100,考虑使用
VirtualizingStackPanel
-
修复 Example 测试中发现的所有 Bug
-
在 README 中添加 PropertyGrid 的使用文档:
- 基础用法示例(XAML 和代码)
- 支持的属性类型列表
- 如何使用 Category Attribute
- 已知限制(如暂不支持嵌套对象)