查找在调用属性的 get 时触发的事件

本文关键字:事件 get 调用 属性 查找 | 更新日期: 2023-09-27 18:32:31

我在我的应用程序中使用了PropertyGrid。我需要在运行时根据自定义数据条件更改某些属性的可见性和只读。

虽然我没有找到一些简单和准备好的东西,但我通过在运行时更改ReadOnlyAttributeBrowsableAttribute属性找到了解决方法,如下所示:

protected void SetBrowsable(string propertyName, bool value)
{
    PropertyDescriptor property = TypeDescriptor.GetProperties(GetType())[propertyName];
    BrowsableAttribute att = (BrowsableAttribute)property.Attributes[typeof(BrowsableAttribute)];
    FieldInfo cat = att.GetType().GetField("browsable", BindingFlags.NonPublic | BindingFlags.Instance);
    if (property.Attributes.Cast<Attribute>().Any(p => p.GetType() == typeof(BrowsableAttribute)))
        cat.SetValue(att, value);
}
protected void SetReadOnly(string propertyName, bool value)
{
    PropertyDescriptor property = TypeDescriptor.GetProperties(GetType())[propertyName];
    ReadOnlyAttribute att = (ReadOnlyAttribute)property.Attributes[typeof(ReadOnlyAttribute)];
    FieldInfo cat = att.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
    if (property.Attributes.Cast<Attribute>().Any(p => p.GetType() == typeof(ReadOnlyAttribute)))
        cat.SetValue(att, value);
}

现在,我的问题是我应该在哪里调用这些方法?我是否可以处理任何事件,以便object调用这些方法?也许通过实现一个接口。

查找在调用属性的 get 时触发的事件

没有

内置事件在调用属性获取时触发,除非您编写了一个。

当然,如果你编写一个自定义描述符(PropertyDescriptor,通常作为装饰器链接到反射描述符(,你可以只通过描述符(数据绑定等(拦截访问,并做任何你想做的事情 - 但对于任意类型(包括那些你没有写的类型(。

在运行时通过反射设置属性值是...不是很好。这主要是由于类型描述符缓存的意外而工作的。如果你要这样做,TypeDescriptor.AddAttributes(或类似(是可取的。但是,通过实现自定义模型可以更恰当地完成您尝试执行的操作。根据显示此内容的位置,可以由一个人或:

  • 添加自定义类型转换器,覆盖 GetProperties,并在运行时根据数据提供自定义描述符 - 主要适用于 PropertyGrid
  • 在对象中实现 ICustomTypeDescriptor,实现 GetProperties,并在运行时根据数据提供自定义描述符 - 适用于大多数控件
  • 添加一个自定义 TypeDescriptionProvider 并与该类型关联 (TypeDescriptor.AddProvider(,提供一个行为类似于上述的 ICustomTypeDescriptor;这将对象与描述符 voodoo 分开

这些都很棘手!最简单的是TypeConverter选项,它运行良好,因为您提到了PropertGrid。从 ExpandableObjectConverter 继承,并覆盖 GetProperties,根据需要进行筛选,并根据需要为只读描述符提供自定义描述符。然后将 TypeConverterAttribute 附加到您的类型,并指定您的自定义转换器类型。

强调:.NET 的这个分支非常复杂、晦涩难懂,并且使用量越来越少。但它有效。