方法一:
///
/// 实体属性处理
///
public class PropertyHandle
{
#region 反射控制只读、可见属性
//SetPropertyVisibility(obj, "名称 ", true);
//obj指的就是你的SelectObject, “名称”是你SelectObject的一个属性
//当然,调用这两个方法后,重新SelectObject一下,就可以了。
///
/// 通过反射控制属性是否只读
///
///
///
///
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);
}
///
/// 通过反射控制属性是否可见
///
///
///
///
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;
///
/// 是否是自增列
///
[Browsable(true)]
[Category("基本")]
[DisplayName("是否是自增列")]
[ReadOnly(false)]
[DefaultValue(false)]
public bool IsIncrementColumn
{
set { isIncrementColumn = value; }
get { return isIncrementColumn; }
}
private Int64 identityIncrement;
///
/// 标识增量
///
[Browsable(true)]
[Category("基本")]
[DisplayName("标识增量")]
[ReadOnly(false)]
[Description("标识增量属性指定在 Microsoft SQL Server 为插入的行生成标识值时,在现有的最大行标识值基础上所加的值。标识增量必须是 非零 整数,位数等于或小于 10。")]
public Int64 IdentityIncrement
{
set { identityIncrement = value; }
get { return identityIncrement; }
}
private Int64 ident_Seed;
///
/// 标识种子
///
[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;
///
/// 是否自增列
///
[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;
}
}
///
/// 是否插入
///
[Category("维护信息")]
[DisplayName("是否插入")]
[ReadOnlyAttribute(false)]
[XmlAttribute]
public bool IsInsert
{
get
;
set
;
}
///
/// 是否更新
///
[Category("维护信息")]
[DisplayName("是否更新")]
[ReadOnlyAttribute(false)]
[XmlAttribute]
public bool IsUpdate
{
get
;
set
;
}
}
通过 PropertyHandle.SetPropertyReadOnly即可实现,效果如下:
演示源码:点击打开链接
本文参考: 如何在设计时中动态改变控件属性在PropertyGrid中显示出来的只读性
小注:
如何修改自定义属性的显示问题呢?
方法二:即参考文章中提到的:Unleash PropertyGrid with Dynamic Properties and Globalization
源码及演示demo下载:点击打开链接