.NET 6 WinForms属性网格中嵌套对象的Browsable属性失效问题
问题原因
你的NestedObjectTypeConverter中,GetProperties方法直接调用TypeDescriptor.GetProperties(typeof(NestedObject)),这个方法默认会返回该类型的所有属性,不会自动过滤标记了[Browsable(false)]的属性,导致PropertyGrid显示了不该显示的属性。
解决方案
修改NestedObjectTypeConverter的GetProperties方法,让它只返回Browsable(true)的属性,有两种实现方式:
方式一:利用TypeDescriptor重载方法过滤
直接使用带筛选参数的GetProperties重载,传入BrowsableAttribute.Yes作为过滤条件:
public class NestedObjectTypeConverter : TypeConverter { public override bool GetPropertiesSupported(ITypeDescriptorContext? context) { return true; } public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext? context, object? value, Attribute[]? attributes) { // 筛选出标记为可浏览的属性 return TypeDescriptor.GetProperties(typeof(NestedObject), new[] { BrowsableAttribute.Yes }); } }
方式二:手动筛选属性
遍历所有属性,检查每个属性的BrowsableAttribute,只保留符合要求的属性:
public class NestedObjectTypeConverter : TypeConverter { public override bool GetPropertiesSupported(ITypeDescriptorContext? context) { return true; } public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext? context, object? value, Attribute[]? attributes) { var allProperties = TypeDescriptor.GetProperties(typeof(NestedObject)); var filteredProperties = new List<PropertyDescriptor>(); foreach (PropertyDescriptor prop in allProperties) { var browsableAttr = prop.Attributes[typeof(BrowsableAttribute)] as BrowsableAttribute; // 未标记Browsable的属性默认可浏览,需一并保留 if (browsableAttr == null || browsableAttr.Browsable) { filteredProperties.Add(prop); } } return new PropertyDescriptorCollection(filteredProperties.ToArray()); } }
关于反射获取Browsable标记的补充
你提到用标准反射获取标记返回null,可能是写法问题,正确的反射获取方式如下:
var prop = typeof(NestedObject).GetProperty("InvisibleValue"); var browsableAttr = prop?.GetCustomAttribute<BrowsableAttribute>(); // 此时browsableAttr不为null,且Browsable属性为false
内容的提问来源于stack exchange,提问作者Slava Lavochkin
相关产品推荐
相关产品推荐

