只读 PropertyGrid
我需要在 PropertyGrid 中显示一个对象,并满足以下要求:该对象及其子对象必须是只读的,能够激活 PropertyGrid 的 CollectionEditors。
我找到了一个与我需要的非常匹配的示例,但有一个我无法弄清楚的意外行为。 我有多个 PropertyGrid,每个 PropertyGrid 用于不同的对象。 在 SetBrowsablePropertiesAsReadOnly 中,我循环一个对象,但令人惊讶的是我的项目中的所有 PropertyGrid 都变为只读。 有人可以帮我吗。 这是代码:
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
I need to show an object in PropertyGrid with the following requirements: the object and its sub object must be read-only, able to activate PropertyGrid's CollectionEditors.
I found a sample that's closely match to what I need but there's an unexpected behaviour I couldn't figure out. I have more than one PropertyGrids each for different objects. In SetBrowsablePropertiesAsReadOnly, I loop one object but suprisingly all of PropertyGrids in my project become readonly. Can anybody help me out. Here's the code:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
ReadOnly
属性是在类定义上设置的,而不是在对象实例上设置的。 因此,这将会对该类的所有实例产生影响。要实现您想要的效果,请创建一个自定义
PropertyDescriptor
,在其中重写IsReadOnly
属性,并将其应用到对象实例的属性。The
ReadOnly
attribute is set on the class definition, not on an instance of an object. Hence this will have an impact on all instances of that class.To achieve what you want, create a custom
PropertyDescriptor
in which you override theIsReadOnly
property, and apply this to the properties of your object instance.我确信这不是正确的 vb 语法,但这可以通过添加属性来完成:
I'm sure this is not correct vb syntax but this can be done by adding an attribute: