关于 syncfusion-wpf-propertygrid
面向构建对象检查器和配置界面的开发者的 Syncfusion WPF PropertyGrid 指南,介绍属性发现、编辑、组织与筛选,以及嵌套属性和集合属性的处理。
主要功能
- 01发现并编辑对象属性
- 02创建自定义值编辑器和类别编辑器
- 03对属性分组和排序
- 04搜索并筛选属性列表
- 05编辑集合和嵌套对象
- 06绑定数据并应用主题
适用场景
- 01构建应用设置编辑器
- 02创建设计时属性检查器
- 03在开发工具中检查对象
- 04根据模型生成配置面板
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ syncfusion/ wpf-ui-components-skills --skill syncfusion-wpf-propertygrid安装后在 Claude Code 中输入/syncfusion-wpf-propertygrid确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/appearance.mdattached-properties.mdcategory-editors.mdcollection-editor.mdcustom-editors.mdcustom-property-definition.mdfiltering.mdgetting-started.mdgrouping.mdkeyboard-navigation.mdlocalization.mdnested-properties.mdoverview.mdproperty-binding.mdsorting.mdvirtualization.md详细介绍
实现 PropertyGrid
Syncfusion® WPF PropertyGrid 控件实现指南——一款功能强大的属性检查器,支持浏览和编辑对象属性,并支持自定义编辑器、类别编辑器、集合编辑、分组、排序、筛选和嵌套属性。
何时使用此技能
在以下情况下使用此技能:
- 显示对象属性,以便浏览和编辑
- 创建属性检查器,类似于 Visual Studio 的“属性”窗口
- 为特定属性类型实现自定义值编辑器
- 对属性进行分组和分类,以便更好地组织
- 编辑集合属性,支持添加、移除和编辑
- 动态筛选和搜索属性
- 支持嵌套属性,并显示可展开的属性项
- 自定义属性显示,包括说明、显示名称和工具提示
- 实现设计时编辑器,用于可视化配置工具
- 构建配置面板,用于应用程序设置
本技能涵盖完整的 PropertyGrid 实现,包括基本设置、属性绑定、编辑器、组织方式和高级自定义。
组件概览
所需程序集:
Syncfusion.PropertyGrid.WPFSyncfusion.SfInput.WPFSyncfusion.SfShared.WPFSyncfusion.Shared.WPFSyncfusion.Tools.WPF
XAML 命名空间:
xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
PropertyGrid 控件提供了一个界面,可用于浏览和编辑任何对象的属性,支持:
- 自动发现属性——自动反射任何对象的属性
- 自定义值编辑器——为特定属性分配自定义控件进行编辑
- 类别编辑器——使用自定义编辑 UI 对相关属性进行分组
- 集合编辑器——内置对话框,用于编辑集合属性(List、ObservableCollection)
- 分组和排序——按类别组织属性,并提供多种排序选项
- 筛选——隐藏属性,并使用内置 SearchBox 进行搜索
- 嵌套属性——展开复杂对象以显示嵌套属性
- Blend 兼容性——支持在 Blend 和 Visual Studio 中进行设计时操作
- 主题——内置主题支持,确保样式一致
- MVVM 支持——全面支持数据绑定和属性更改通知
控件结构
PropertyGrid
├── SearchBox (optional) - Filter properties by name
├── Sort/Group Buttons - Toggle between sorted and categorized views
├── Property List
│ ├── Property Name Column
│ └── Value Editor Column (context-sensitive editors)
└── Description Panel (optional) - Shows property description
文档和导航指南
入门
📄 阅读: references/getting-started.md
- 安装和程序集部署
- 通过设计器、XAML 和 C# 添加 PropertyGrid
- 使用 SelectedObject 进行绑定
- 自动填充属性
- 基本配置和设置
- 主题支持
📄 阅读: references/overview.md
- 控件结构和架构
- 功能概览和能力
- 用例和场景
- 何时使用 PropertyGrid
📄 阅读: references/property-binding.md
- SelectedObject 绑定
- 数据上下文配置
- INotifyPropertyChanged 实现
- ObservableCollection 用法
- 动态属性更新
- 绑定多个对象
编辑器和自定义
📄 阅读: references/custom-editors.md
- 创建自定义编辑器(ITypeEditor 接口)
- 通过 Editor 特性分配编辑器
- 使用 CustomEditorCollection
- 按属性名称或属性类型分配
- EditorType 与 Editor 属性
- 带参数的构造函数
- Attach/Create/Detach 方法
- 自定义编辑器控件
📄 阅读: references/category-editors.md
- CategoryEditor 概念
- 对相关属性进行分组
- 自定义 EditorTemplate
- 对多个属性进行分类
- 可见性转换器
- 自定义类别布局
📄 阅读: references/collection-editor.md
- 编辑集合属性(List、ObservableCollection)
- 添加/移除项目对话框
- 将集合作为 SelectedObject 编辑
- 嵌套集合编辑
- 只读模式配置
- CollectionEditorOpening 事件
- IList 类型要求
📄 阅读: references/custom-property-definition.md
- 手动定义 PropertyItem
- 配置 PropertyGridItem
- AutoGenerateItems 属性
- 在运行时添加/移除项目
- 自定义 DisplayName、Description、CategoryName
- 自定义编辑器和嵌套属性
- 描述面板模板
组织功能
📄 阅读: references/grouping.md
- EnableGrouping 属性
- 按 Category 特性分组
- 自定义组外观
- 展开/折叠行为
- 组按钮可见性
📄 阅读: references/sorting.md
- SortDirection 属性(Ascending、Descending、Null)
- 按名称对属性排序
- 对类别排序
- 使用 Order 特性自定义排序
- 用 ButtonPanelVisibility 控制排序按钮
- 禁用排序
📄 阅读: references/filtering.md
- 使用 HidePropertiesCollection 隐藏属性
- Browsable 特性(设为 false 即可隐藏)
- Bindable 特性(设为 false 即可隐藏)
- Display.AutoGenerateField 特性
- AutoGeneratingPropertyGridItem 事件
- 使用 SearchBox 按名称筛选
- SearchBoxVisibility 属性
📄 阅读: references/nested-properties.md
- PropertyExpandMode(FlatMode 与 NestedMode)
- NestedPropertyDisplayMode 属性
- 展开复杂对象属性
- 失去焦点时更新值
- 手动定义嵌套属性
外观和行为
📄 阅读: references/appearance.md
- 视觉样式和主题
- 属性名称/值的外观
- 自定义描述面板
- DescriptionPanelVisibility 属性
- 网格线和间距
- 颜色自定义
📄 阅读: references/attached-properties.md
- 使用 WPF 附加属性
- PropertyGrid 专用附加属性
- 配置示例
📄 阅读: references/keyboard-navigation.md
- 键盘快捷键
- 在属性间使用 Tab 导航
- Enter/Escape 行为
- 焦点管理
📄 阅读: references/localization.md
- 本地化支持
- 资源文件配置
- 特定区域性的字符串
- 自定义内置文本
📄 阅读: references/virtualization.md
- VirtualizingMode 属性
- 优化大型属性集的性能
- 内存管理
- 滚动行为
快速入门示例
基本 PropertyGrid 设置
<Window x:Class="PropertyGridSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:syncfusion="http://schemas.syncfusion.com/wpf">
<Grid>
<syncfusion:PropertyGrid Name="propertyGrid1"
SelectedObject="{Binding SelectedEmployee}"
Width="400" Height="500">
<syncfusion:PropertyGrid.DataContext>
<local:ViewModel/>
</syncfusion:PropertyGrid.DataContext>
</syncfusion:PropertyGrid>
</Grid>
</Window>
// Employee class to be explored in PropertyGrid
public class Employee : INotifyPropertyChanged
{
private string name;
public string Name
{
get => name;
set { name = value; OnPropertyChanged(nameof(Name)); }
}
[Display(Name = "Employee ID")]
[Description("Unique identifier for the employee")]
public string ID { get; set; }
[Category("Personal Info")]
[DisplayName("Date of Birth")]
public DateTime DOB { get; set; }
[Category("Personal Info")]
[Range(18, 65)]
public int Age { get; set; }
[Browsable(false)] // Hide this property
public string InternalCode { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// ViewModel
public class ViewModel
{
public object SelectedEmployee { get; set; }
public ViewModel()
{
SelectedEmployee = new Employee
{
Name = "Johnson",
Age = 25,
ID = "EMP001",
DOB = new DateTime(1999, 5, 15)
};
}
}
常见模式
模式 1:为 Email 属性创建自定义编辑器
// Custom Editor with email validation mask
public class EmailEditor : ITypeEditor
{
SfMaskedEdit maskedEdit;
public object Create(PropertyInfo propertyInfo)
{
maskedEdit = new SfMaskedEdit
{
MaskType = MaskType.RegEx,
Mask = "[A-Za-z0-9._%-]+@[A-Za-z0-9]+.[A-Za-z]{2,3}"
};
return maskedEdit;
}
public void Attach(PropertyViewItem property, PropertyItem info)
{
var binding = new Binding("Value")
{
Mode = BindingMode.TwoWay,
Source = info,
ValidatesOnExceptions = true,
ValidatesOnDataErrors = true
};
BindingOperations.SetBinding(maskedEdit, SfMaskedEdit.ValueProperty, binding);
}
public void Detach(PropertyViewItem property) { }
}
// Apply to property
public class Employee
{
[Editor("EmailID", typeof(EmailEditor))]
public string EmailID { get; set; }
}
模式 2:按类别对属性分组
public class Employee
{
[Category("Basic Info")]
public string Name { get; set; }
[Category("Basic Info")]
public string ID { get; set; }
[Category("Contact Details")]
public string Email { get; set; }
[Category("Contact Details")]
public string Phone { get; set; }
}
<syncfusion:PropertyGrid SelectedObject="{Binding Employee}"
EnableGrouping="True"/>
模式 3:编辑集合属性
public class Product
{
public string ProductName { get; set; }
// Collection property - automatically gets collection editor
public ObservableCollection<Customer> Customers { get; set; }
public Product()
{
Customers = new ObservableCollection<Customer>
{
new Customer { ID = 1, Name = "John" },
new Customer { ID = 2, Name = "Jane" }
};
}
}
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
}
模式 4:在运行时重写属性项
private void PropertyGrid_AutoGeneratingPropertyGridItem(
object sender, AutoGeneratingPropertyGridItemEventArgs e)
{
// Hide specific properties
if (e.DisplayName == "InternalCode")
{
e.Cancel = true;
}
// Make property readonly
if (e.DisplayName == "ID")
{
e.ReadOnly = true;
}
// Change display name
if (e.DisplayName == "DOB")
{
e.DisplayName = "Date of Birth";
}
// Change category
if (e.DisplayName == "Age")
{
e.Category = "Personal Information";
}
}
模式 5:属性值更改通知
private void PropertyGrid_ValueChanged(object sender, ValueChangedEventArgs e)
{
var changedProperty = e.Property;
var oldValue = e.OldValue;
var newValue = e.NewValue;
// Log the change
Console.WriteLine($"{changedProperty.Name} changed from {oldValue} to {newValue}");
// React to specific property changes
if (changedProperty.Name == "Age")
{
// Validate or update related properties
}
}
关键属性
核心属性
| 属性 | 类型 | 描述 |
|---|---|---|
| SelectedObject | object | 显示其属性的对象 |
| SelectedObjects | object[] | 用于共同编辑属性的多个对象 |
| EnableGrouping | bool | 按类别对属性分组 |
| SortDirection | ListSortDirection? | 对属性排序(Ascending、Descending、null) |
| PropertyExpandMode | PropertyExpandModes | 复杂对象的 FlatMode 或 NestedMode |
| AutoGenerateItems | bool | 自动生成属性项(默认值:true) |
UI 配置
| 属性 | 类型 | 描述 |
|---|---|---|
| SearchBoxVisibility | Visibility | 显示/隐藏搜索框 |
| ButtonPanelVisibility | Visibility | 显示/隐藏排序/分组按钮 |
| DescriptionPanelVisibility | Visibility | 显示/隐藏描述面板 |
| EnableToolTip | bool | 为属性项启用工具提示 |
| DisableAnimationOnObjectSelection | bool | 禁用加载动画 |
集合
| 属性 | 类型 | 描述 |
|---|---|---|
| HidePropertiesCollection | ObservableCollection | 要隐藏的属性名称 |
| CustomEditorCollection | CustomEditorCollection | 属性的自定义编辑器 |
| Items | PropertyGridItemCollection | 手动定义的属性项 |
事件
| 事件 | 描述 |
|---|---|
| AutoGeneratingPropertyGridItem | 创建属性项时触发(可取消或修改) |
| ValueChanged | 属性值更改时触发 |
| SelectedPropertyItemChanged | 所选属性更改时触发 |
| CollectionEditorOpening | 集合编辑器打开前触发(可取消或设为只读) |
常见用例
1. 应用程序设置编辑器
按类别(外观、行为、性能)分组显示和编辑应用程序配置。
2. 设计时属性检查器
为自定义控件或组件创建可视化设计器,以便编辑属性。
3. 开发工具中的对象检查器
构建调试或检查工具,以便在运行时查看和修改对象属性。
4. 动态配置面板
根据数据模型类自动生成配置 UI,无需手动设计表单。
5. 包含复杂对象的数据录入表单
显示包含集合的嵌套对象属性,允许用户编辑分层数据。
6. 报表参数配置
允许用户配置报表参数,并为每种数据类型提供适当的编辑器。
7. 游戏/应用程序资源编辑器
编辑游戏对象、场景或资源的属性,并为向量、颜色和资源提供自定义编辑器。
8. 业务规则配置
通过基于属性的配置和验证来定义和编辑业务规则。
相关组件
- PropertyGridItem - 单个属性项的表示
- CustomEditor - 自定义值编辑器配置
- CategoryEditor - 基于类别的属性分组
- Collection Editor - 内置集合编辑对话框
最佳实践
-
使用特性添加元数据
- 为属性应用
[Category]、[Description]、[DisplayName]特性 - 使用
[Browsable(false)]隐藏属性,而不是通过代码筛选
- 为属性应用
-
实现 INotifyPropertyChanged
- 确保数据对象实现属性变更通知
- 对集合属性使用
ObservableCollection
-
为复杂类型创建自定义编辑器
- 为没有合适默认编辑器的类型创建自定义编辑器
- 设计自定义编辑器 UI 时考虑用户体验
-
处理大型对象的性能问题
- 对包含许多属性的对象使用虚拟化
- 考虑对嵌套属性进行延迟加载
- 尽早筛选不需要的属性
-
验证
- 使用数据注释进行验证(
[Required]、[Range]等) - 在自定义编辑器中妥善处理验证错误
- 使用数据注释进行验证(
-
无障碍性
- 确保自定义编辑器支持键盘导航
- 为屏幕阅读器提供有意义的描述
- 使用高对比度主题进行测试
故障排除
属性未显示
- 确认
[Browsable]特性未设为 false - 检查属性是否位于
HidePropertiesCollection中 - 确保属性具有公共 getter
- 确认
AutoGenerateItems为 true
自定义编辑器未应用
- 检查编辑器是否已在
CustomEditorCollection中正确注册 - 确认属性名称/类型匹配
- 确保编辑器正确实现
ITypeEditor - 检查
Create方法是否返回有效控件
集合编辑器未打开
- 确认集合类型派生自
IList - 确保集合属性具有 setter
- 检查集合类型是否具有无参数构造函数
- 确认
CollectionEditorOpening事件未取消操作
性能问题
- 为大型属性集启用虚拟化
- 减少嵌套属性深度
- 筛选不需要的属性
- 考虑手动定义属性,而不是自动生成
后续步骤: 根据实现需求,前往上方的特定参考文档。首先参阅 getting-started.md 完成初始设置,然后按需探索编辑器和组织功能。