XCeed PropertyGrid:如何添加bool(CheckBox)类型的自定义PropertyDefinition属性
给PropertyGrid添加bool类型(CheckBox)属性的正确方法
你的代码问题出在HasAttribute的错误用法——这个属性是用来筛选带有指定特性的现有属性,不是用来定义属性类型的。以下分两种场景给出解决方案:
场景1:目标对象可以直接添加属性(推荐)
如果PropertyGrid绑定的对象(SelectedObject)是你可控的类,直接在类里定义KeepRatio属性即可,PropertyGrid会自动识别bool类型并显示为CheckBox:
// 你的目标类 public class LayoutSettings { [Category("Layout")] // 指定分类 [DisplayName("KeepRatio")] // 显示名称 public bool KeepRatio { get; set; } = false; // 默认值 } // 绑定到PropertyGrid propertyGrid1.SelectedObject = new LayoutSettings();
如果是用Telerik的PropertyGrid(你的代码里用到了PropertyDefinitions),也可以手动添加定义(但其实控件会自动识别属性,手动添加是为了自定义显示逻辑):
var propertyDefinition = new PropertyDefinition() { Category = "Layout", DisplayName = "KeepRatio", TargetProperties = new string[] { "KeepRatio" } // 无需设置HasAttribute,控件会根据属性类型自动使用CheckBox编辑器 }; propertyGrid1.PropertyDefinitions.Add(propertyDefinition);
场景2:无法修改目标对象,动态添加属性
如果绑定的对象是第三方类,无法直接添加属性,可以通过自定义TypeDescriptor动态注入属性:
1. 实现自定义类型描述器相关类
using System.ComponentModel; public class CustomTypeProvider : TypeDescriptionProvider { private readonly TypeDescriptionProvider _baseProvider; public CustomTypeProvider(TypeDescriptionProvider baseProvider) { _baseProvider = baseProvider; } public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) { var baseDescriptor = _baseProvider.GetTypeDescriptor(objectType, instance); return new CustomPropertyDescriptorWrapper(baseDescriptor); } } public class CustomPropertyDescriptorWrapper : CustomTypeDescriptor { public CustomPropertyDescriptorWrapper(ICustomTypeDescriptor parent) : base(parent) { } public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { var originalProps = base.GetProperties(attributes); var customProps = new List<PropertyDescriptor>(); // 添加自定义的KeepRatio属性 var keepRatioProp = new DynamicBoolProperty( "KeepRatio", new CategoryAttribute("Layout"), new DisplayNameAttribute("KeepRatio") ); customProps.AddRange(originalProps.Cast<PropertyDescriptor>()); customProps.Add(keepRatioProp); return new PropertyDescriptorCollection(customProps.ToArray()); } } public class DynamicBoolProperty : PropertyDescriptor { private bool _currentValue; public DynamicBoolProperty(string name, params Attribute[] attrs) : base(name, attrs) { _currentValue = false; } public override bool CanResetValue(object component) => true; public override object GetValue(object component) => _currentValue; public override void ResetValue(object component) => _currentValue = false; public override void SetValue(object component, object value) => _currentValue = (bool)value; public override bool ShouldSerializeValue(object component) => true; public override Type ComponentType => typeof(object); public override bool IsReadOnly => false; public override Type PropertyType => typeof(bool); }
2. 应用到目标对象并绑定
// 假设你的原始对象是thirdPartyObject var provider = new CustomTypeProvider(TypeDescriptor.GetProvider(thirdPartyObject)); TypeDescriptor.AddProvider(provider, thirdPartyObject); propertyGrid1.SelectedObject = thirdPartyObject;
这样PropertyGrid就会显示动态添加的KeepRatio复选框属性。
内容的提问来源于stack exchange,提问作者Muhammad Salman
相关产品推荐
相关产品推荐

