方法一:
/// <summary> /// 实体属性处理 /// </summary> public class PropertyHandle { #region 反射控制只读、可见属性 //SetPropertyVisibility(obj, "名称 ", true); //obj指的就是你的SelectObject, “名称”是你SelectObject的一个属性 //当然,调用这两个方法后,重新SelectObject一下,就可以了。 /// <summary> /// 通过反射控制属性是否只读 /// </summary> /// <param name="obj"></param> /// <param name="propertyName"></param> /// <param name="readOnly"></param> public static void SetPropertyReadOnly(object obj, string propertyName, bool readOnly) { Type type = typeof(ReadOnlyAttribute); PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj); AttributeCollection attrs = props[propertyName].Attributes; FieldInfo fld = type.GetField("isReadOnly", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance); fld.SetValue(attrs[type], readOnly); } /// <summary> /// 通过反射控制属性是否可见 /// </summary> /// <param name="obj"></param> /// <param name="propertyName"></param> /// <param name="visible"></param> public static void SetPropertyVisibility(object obj, string propertyName, bool visible) { Type type = typeof(BrowsableAttribute); PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj); AttributeCollection attrs = props[propertyName].Attributes; FieldInfo fld = type.GetField("browsable", BindingFlags.Instance | BindingFlags.NonPublic); fld.SetValue(attrs[type], visible); } #endregion }举例: 比如某个实体类TestEntity中有自增列(IdentityColumnInfo)这么一个属性, 该自增列对应的实体类如下:
public class IdentityColumnEntity { private bool isIncrementColumn; /// <summary> /// 是否是自增列 /// </summary> [Browsable(true)] [Category("基本")] [DisplayName("是否是自增列")] [ReadOnly(false)] [DefaultValue(false)] public bool IsIncrementColumn { set { isIncrementColumn = value; } get { return isIncrementColumn; } } private Int64 identityIncrement; /// <summary> /// 标识增量 /// </summary> [Browsable(true)] [Category("基本")] [DisplayName("标识增量")] [ReadOnly(false)] [Description("标识增量属性指定在 Microsoft SQL Server 为插入的行生成标识值时,在现有的最大行标识值基础上所加的值。标识增量必须是 非零 整数,位数等于或小于 10。")] public Int64 IdentityIncrement { set { identityIncrement = value; } get { return identityIncrement; } } private Int64 ident_Seed; /// <summary> /// 标识种子 /// </summary> [Browsable(true)] [Category("基本")] [DisplayName("标识种子")] [ReadOnly(false)] [Description("指示标识列的初始行值。标识种子必须是 整数,位数等于或小于 10。")] public Int64 Ident_Seed { set { ident_Seed = value; } get { return ident_Seed; } } }实体类 TestEntity代码如下:
public class TestEntity { private IdentityColumnEntity identityColumnInfo; /// <summary> /// 是否自增列 /// </summary> [Category("扩展信息")] [DisplayName("自增列信息")] [ReadOnlyAttribute(true)] [XmlIgnore] [Browsable(true)] //[XmlAttribute] public IdentityColumnEntity IdentityColumnInfo { get { if (identityColumnInfo != null && identityColumnInfo.IsIncrementColumn) { PropertyHandle.SetPropertyReadOnly(identityColumnInfo, "Ident_Seed", true); PropertyHandle.SetPropertyReadOnly(identityColumnInfo, "IdentityIncrement", true); PropertyHandle.SetPropertyReadOnly(identityColumnInfo, "IsIncrementColumn", true); PropertyHandle.SetPropertyReadOnly(this, "IsInsert", true); PropertyHandle.SetPropertyReadOnly(this, "IsUpdate", true); } return identityColumnInfo; } set { identityColumnInfo = value; } } /// <summary> /// 是否插入 /// </summary> [Category("维护信息")] [DisplayName("是否插入")] [ReadOnlyAttribute(false)] [XmlAttribute] public bool IsInsert { get ; set ; } /// <summary> /// 是否更新 /// </summary> [Category("维护信息")] [DisplayName("是否更新")] [ReadOnlyAttribute(false)] [XmlAttribute] public bool IsUpdate { get ; set ; } }通过 PropertyHandle.SetPropertyReadOnly即可实现,效果如下:
演示源码:点击打开链接
本文参考: 如何在设计时中动态改变控件属性在PropertyGrid中显示出来的只读性
小注:
如何修改自定义属性的显示问题呢?
方法二:即参考文章中提到的:Unleash PropertyGrid with Dynamic Properties and Globalization
源码及演示demo下载:点击打开链接