C# 设计时动态改变实体在PropertyGrid中显示出来的属性

原创 2015年11月21日 12:45:20

方法一:

    /// <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下载:点击打开链接






版权声明:作者:jiankunking 出处:http://blog.csdn.net/jiankunking 本文版权归作者和CSDN共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

相关文章推荐

C# winform动态添加属性控件propertyGrid1的项

private void Form1_Load(object sender, EventArgs e)         {             object[] s = new object[] ...

如何在程序运行中动态改变对象属性在PropertyGrid可见性和只读属性

以下两个方法分别实现可见性和只读属性的动态改变: void SetPropertyVisibility(object obj, string propertyName, bool visible) {...

C#自定义PropertyGrid属性

最近用到了PropertyGrid,原来从来没用到过,拿在手里,一头雾水,经过一段时间研究后,大概理解了Property的使用方法,下面仔细剖析一下。 PropertyGrid控件就是Visual ...
  • jjhua
  • jjhua
  • 2014年04月07日 13:40
  • 14954

C# Dev控件中的 PropertyGridControl 属性控件的基本用法以及排序

在这个例子中将实现让该属性控件实现排序按钮。 效果如图:   首先2个按钮是 CheckButton 控件。 然后是一个:PropertyGridControl  控件   为了美观一...

用反射实现PropertyGrid中的属性动态实现只读、可见

用反射可以实现动态改变,只读、可见等等,这些属性都可以改变。  以下两个方法分别实现可见性和只读属性的动态改变:  void   SetPropertyVisibility(object   ob...
  • fgjfj
  • fgjfj
  • 2016年05月31日 21:52
  • 464

C# 自定义属性在propertyGrid控件中显示

在上篇文章(地址: C# 设计时动态改变实体在PropertyGrid中显示出来的属性)中可以看到:自定义属性的显示是有问题的,那么如何修改呢?代码如下:public class PropertyDi...

C#中PropertyGrid控件绑定对象后更改属性值写回到xml中的一个有效方法

这两天项目开发过程中遇到的一个问题,就是PropertyGrid控件的对象的属性值修改后怎么写回到xml中的问题 由于属性项不统一,不能每个类的属性都去写一个单独的方法,这样需啊的类和方法就特别多,处...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

动态填充/修改类属性的 DisplayNameAttribute 属性

话说 PropertyDescriptor 的许多属性都是只读的。包括 DisplayName 属性,最初的时候,用Reflector 反编译然后查看里面的私有字段和属性,然后用反射机制强行设置,虽然...
  • Baple
  • Baple
  • 2012年03月12日 17:46
  • 6302

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# 设计时动态改变实体在PropertyGrid中显示出来的属性
举报原因:
原因补充:

(最多只允许输入30个字)