【问题标题】:Read-only PropertyGrid只读 PropertyGrid
【发布时间】:2008-12-15 04:03:28
【问题描述】:

我需要在 PropertyGrid 中显示一个对象,要求如下:该对象及其子对象必须是只读的,能够激活 PropertyGrid 的 CollectionEditors。

我找到了一个与我需要的非常匹配的样本,但有一个我无法弄清楚的意外行为。对于不同的对象,我有多个 PropertyGrids。在 SetBrowsablePropertiesAsReadOnly 中,我循环了一个对象,但令人惊讶的是,我项目中的所有 PropertyGrids 都变成了只读的。谁能帮帮我。代码如下:



Imports System.Reflection
Imports System.ComponentModel

Public Class PropertyGridEx
    Inherits PropertyGrid

    Private isReadOnly As Boolean
    Public Property [ReadOnly]() As Boolean
        Get
            Return Me.isReadOnly
        End Get
        Set(ByVal value As Boolean)
            Me.isReadOnly = value
            Me.SetBrowsablePropertiesAsReadOnly(Me.SelectedObject, value)
        End Set
    End Property

    Protected Overloads Sub OnSelectedObjectsChanged(ByVal e As EventArgs)
        Me.SetBrowsablePropertiesAsReadOnly(Me.SelectedObject, Me.isReadOnly)
        MyBase.OnSelectedObjectsChanged(e)
    End Sub

    Private Sub SetBrowsablePropertiesAsReadOnly(ByRef selectedObject As Object, ByVal isReadOnly As Boolean)
        If selectedObject IsNot Nothing Then
            Dim props As PropertyDescriptorCollection = TypeDescriptor.GetProperties(selectedObject)
            For Each propDescript As PropertyDescriptor In props
                If propDescript.IsBrowsable AndAlso propDescript.PropertyType.GetInterface("ICollection", True) Is Nothing Then
                    Dim attr As ReadOnlyAttribute = TryCast(propDescript.Attributes(GetType(ReadOnlyAttribute)), ReadOnlyAttribute)
                    If attr IsNot Nothing Then
                        Dim field As FieldInfo = attr.[GetType]().GetField("isReadOnly", BindingFlags.NonPublic Or BindingFlags.Instance)
                        field.SetValue(attr, isReadOnly, BindingFlags.NonPublic Or BindingFlags.Instance, Nothing, Nothing)
                    End If
                End If
            Next
        End If
    End Sub
End Class

【问题讨论】:

    标签: .net reflection propertygrid propertydescriptor readonly-attribute


    【解决方案1】:

    ReadOnly 属性是在类定义上设置的,而不是在对象的实例上设置的。因此,这将对该类的所有实例产生影响。

    要实现您想要的,请创建一个自定义 PropertyDescriptor,在其中覆盖 IsReadOnly 属性,并将其应用于您的对象实例的属性。

    【讨论】:

      【解决方案2】:

      我确定这不是正确的 vb 语法,但这可以通过添加属性来完成:

      Private Sub SetBrowsablePropertiesAsReadOnly(ByRef selectedObject As Object, ByVal isReadOnly As Boolean)
        If selectedObject IsNot Nothing Then
          TypeDescriptor.AddAttributes(selectedObject, New Attribute[] { New ReadOnlyAttribute(isReadOnly) });
        End If
      End Sub
      

      【讨论】:

        猜你喜欢
        • 2012-05-15
        • 2023-03-12
        • 1970-01-01
        • 2010-12-05
        • 1970-01-01
        • 1970-01-01
        • 2015-05-10
        • 1970-01-01
        相关资源
        最近更新 更多