我需要在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
答案 0 :(得分:0)
ReadOnly
属性是在类定义上设置的,而不是在对象的实例上设置的。因此,这将对该类的所有实例产生影响。
要实现您的目标,请创建一个自定义PropertyDescriptor
,在其中覆盖IsReadOnly
属性,并将其应用于对象实例的属性。
答案 1 :(得分:0)
我确定这不是正确的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