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

简介: 方法一: /// <summary> /// 实体属性处理 /// </summary> public class PropertyHandle { #region 反射控制只读、可见属性 //SetPropertyVisibility(obj, "名称 ", true);

方法一:

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






目录
相关文章
|
8月前
|
存储 安全 编译器
C# 11.0中的泛型属性:类型安全的新篇章
【1月更文挑战第23天】C# 11.0引入了泛型属性的概念,这一新特性为开发者提供了更高级别的类型安全性和灵活性。本文将详细探讨C# 11.0中泛型属性的工作原理、使用场景以及它们对现有编程模式的改进。通过深入了解泛型属性,开发者将能够编写更加健壮、可维护的代码,并充分利用C#语言的最新发展。
|
C# Windows 容器
C#或Winform中的消息通知之系统托盘的气泡提示窗口(系统toast通知)、ToolTip控件和ToolTipText属性
NotifyIcon控件表示系统右下角任务栏上的托盘图标,其ShowBalloonTip方法用于显示气球状提示框(Win10只有为本地Toast通知),ToolTip\oolTipText可以...
2089 0
C#或Winform中的消息通知之系统托盘的气泡提示窗口(系统toast通知)、ToolTip控件和ToolTipText属性
|
20天前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
72 12
|
4月前
|
安全 C# 索引
C#一分钟浅谈:属性与索引器的定义
本文深入浅出地介绍了C#编程中的属性和索引器。属性让字段更安全,通过访问器方法在读写时执行额外操作,如验证数据有效性;索引器则赋予类数组般的访问方式,支持基于索引的数据访问模式。文章通过示例代码展示了如何定义及使用这两种特性,并提供了常见问题及其解决方案,帮助读者写出更健壮、易维护的代码。希望读者能从中学习到如何有效利用属性和索引器增强C#类的功能性。
118 12
|
8月前
|
存储 编译器 C#
|
5月前
|
存储 安全 编译器
C#中的属性
C#中的属性
54 7
|
7月前
|
开发框架 .NET 编译器
程序与技术分享:C#基础知识梳理系列三:C#类成员:常量、字段、属性
程序与技术分享:C#基础知识梳理系列三:C#类成员:常量、字段、属性
46 2
|
6月前
|
C#
C#中使用IntPtr.Size属性来判断当前系统是32位还是64位
这段代码首先检查 `IntPtr.Size`的值,如果是4,则输出"当前系统是32位";如果是8,则输出"当前系统是64位";如果都不是,就输出"未知系统位数"。
100 0
|
8月前
|
存储 JSON C#
C# 通过阿里云接口实现人脸属性识别
C# 通过阿里云接口实现人脸属性识别
|
8月前
|
Java C#
C#学习相关系列之多线程(七)---Task的相关属性用法
C#学习相关系列之多线程(七)---Task的相关属性用法