是否可以在设计时更改属性属性的值? [英] Is it possible to change the value of a property attribute at design time?
问题描述
我的User Control
上有一个Property
,它像这样在设计模式下隐藏了</p>
I have a Property
on my User Control
that is hidden in design mode like so
<Browsable(False)>
Public Property MyProperty As Object
我想根据另一个Property
的值将其更改为True
.
What i would like to do is change it to True
depending on the value of another Property
.
类似
Private _otherProperty As Boolean
Public Property OtherProperty() As Boolean
Get
Return _otherProperty
End Get
Set(ByVal value As Boolean)
_otherProperty = value
If value = True Then
'Set MyProperty Browsable Attribute True here
Else
'Set MyProperty Browsable Attribute False here
End If
End Set
End Property
这就是我的想法.
基本上我希望Property
仅在另一个Property
设置为True
时在设计时可用,但找不到在设计模式下更改属性值的方法.
Basically i want a Property
to only be available at design time when another Property
is set to True
but can't find a way to change the attribute value in design mode.
推荐答案
WinForm设计器的PropertyGrid中显示的属性通过 ICustomTypeDescriptor接口.
The properties displayed in the WinForm designer's PropertyGrid are managed via PropertyDescriptors. You can control the descriptors returned by the inspection mechanisms by a couple of different ways. A relatively simple (while tedious) way is have your class implement the ICustomTypeDescriptor Interface.
让我们假设您的usercontrol类定义如下:
Let us assume your usercontrol class is defined as follows:
Imports System.ComponentModel
Public Class DemoUC
Public Sub New()
InitializeComponent()
End Sub
<RefreshProperties(RefreshProperties.All)>
Public Property OtherProperty As Boolean
<Browsable(False)>
Public Property MyProperty As String
End Class
注意 RefreshPropertiesAttribute 装饰OtherProperty
.这将告诉PropertyGrid每次此属性更改时都拉动所有属性.这是必需的,以便在OtherProperty
为true时显示MyProperty
属性的逻辑起作用.
Notice the RefreshPropertiesAttribute decorating OtherProperty
. This will tell the PropertyGrid to pull all properties each time this property changes. This is needed so that logic to display the MyProperty
property when OtherProperty
is true will work.
在另一个类文件中,添加以下实现ICustomTypeDescriptor Interface
的部分类.
In another class file, add the following partial class that implements the ICustomTypeDescriptor Interface
.
Imports System.ComponentModel
Partial Public Class DemoUC : Implements ICustomTypeDescriptor
Public Function GetAttributes() As AttributeCollection Implements ICustomTypeDescriptor.GetAttributes
Return TypeDescriptor.GetAttributes(Me, True)
End Function
Public Function GetClassName() As String Implements ICustomTypeDescriptor.GetClassName
Return TypeDescriptor.GetClassName(Me, True)
End Function
Public Function GetComponentName() As String Implements ICustomTypeDescriptor.GetComponentName
Return TypeDescriptor.GetComponentName(Me, True)
End Function
Public Function GetConverter() As TypeConverter Implements ICustomTypeDescriptor.GetConverter
Return TypeDescriptor.GetConverter(Me, True)
End Function
Public Function GetDefaultEvent() As EventDescriptor Implements ICustomTypeDescriptor.GetDefaultEvent
Return TypeDescriptor.GetDefaultEvent(Me, True)
End Function
Public Function GetDefaultProperty() As PropertyDescriptor Implements ICustomTypeDescriptor.GetDefaultProperty
Return TypeDescriptor.GetDefaultProperty(Me, True)
End Function
Public Function GetEditor(editorBaseType As Type) As Object Implements ICustomTypeDescriptor.GetEditor
Return TypeDescriptor.GetEditor(Me, editorBaseType, True)
End Function
Public Function GetEvents() As EventDescriptorCollection Implements ICustomTypeDescriptor.GetEvents
Return TypeDescriptor.GetEvents(Me, True)
End Function
Public Function GetEvents(attributes() As Attribute) As EventDescriptorCollection Implements ICustomTypeDescriptor.GetEvents
Return TypeDescriptor.GetEvents(Me, attributes, True)
End Function
Public Function GetProperties() As PropertyDescriptorCollection Implements ICustomTypeDescriptor.GetProperties
Return GetProperties({})
End Function
Public Function GetProperties(attributes() As Attribute) As PropertyDescriptorCollection Implements ICustomTypeDescriptor.GetProperties
Dim basePDs As New PropertyDescriptorCollection(Nothing, False)
For Each pd As PropertyDescriptor In TypeDescriptor.GetProperties(Me, attributes, True)
basePDs.Add(pd)
Next
If Me.DesignMode AndAlso Me.OtherProperty Then
Dim pd As PropertyDescriptor = TypeDescriptor.GetProperties(Me, True).Cast(Of PropertyDescriptor).Where(Function(desc As PropertyDescriptor) desc.Name.Equals(NameOf(Me.MyProperty))).FirstOrDefault()
If basePDs.Contains(pd) Then
basePDs.Remove(pd)
End If
basePDs.Add(New BrowsableDescriptor(pd))
End If
Return basePDs
End Function
Public Function GetPropertyOwner(pd As PropertyDescriptor) As Object Implements ICustomTypeDescriptor.GetPropertyOwner
Return Me
End Function
Class BrowsableDescriptor : Inherits PropertyDescriptor
Private src As PropertyDescriptor
Public Sub New(src As PropertyDescriptor)
MyBase.New(src.Name, Nothing)
Me.src = src
Dim attribs As New List(Of Attribute)
For Each att As Attribute In src.Attributes
If TypeOf att Is BrowsableAttribute Then Continue For
attribs.Add(att)
Next
attribs.Add(BrowsableAttribute.Yes)
MyBase.AttributeArray = attribs.ToArray
End Sub
Public Overrides ReadOnly Property IsBrowsable As Boolean
Get
Return True
End Get
End Property
Public Overrides ReadOnly Property ComponentType As Type
Get
Return src.ComponentType
End Get
End Property
Public Overrides ReadOnly Property IsReadOnly As Boolean
Get
Return src.IsReadOnly
End Get
End Property
Public Overrides ReadOnly Property PropertyType As Type
Get
Return src.PropertyType
End Get
End Property
Public Overrides Sub ResetValue(component As Object)
src.ResetValue(component)
End Sub
Public Overrides Sub SetValue(component As Object, value As Object)
src.SetValue(component, value)
End Sub
Public Overrides Function CanResetValue(component As Object) As Boolean
Return src.CanResetValue(component)
End Function
Public Overrides Function GetValue(component As Object) As Object
Return src.GetValue(component)
End Function
Public Overrides Function ShouldSerializeValue(component As Object) As Boolean
Return src.ShouldSerializeValue(component)
End Function
End Class
End Class
大多数实现只返回基本的TypeDescriptor
提供的内容. GetProperties
函数是在其中实现的逻辑,用于使用可浏览的逻辑替换MyProperty
属性的不可浏览的PropertyDescriptor.
The majority of the implementation just returns what the base TypeDescriptor
would provide. The GetProperties
function is where the logic is implemented to replace the non-browsable PropertyDescriptor for the MyProperty
property with a browsable one takes place.
这是代码编译后,DemoUC
控件将在PropertyGrid中显示如下.观察到MyProperty
是根据OtherProperty
的值显示/隐藏的.
Once this is code is compiled, the DemoUC
control will display like this in the PropertyGrid. Observe that MyProperty
is shown/Hidden based on the value of OtherProperty
.
这篇关于是否可以在设计时更改属性属性的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!