在设计时更改可用属性 [英] Changing available Properties at design time
问题描述
我有一个自定义控件,可以使用四个不同的图像。这些图像在各种主题下存储为资产,这样星际主题将有四个基于星形的图像。
控件有一个主题属性,但我想扩展概念,以便可以创建用户定义的主题。
我希望将'UserDefined'添加到我的主题枚举中,如果这样从属性页面中选择选项然后我想显示四个新属性,从中可以设置四个用户定义的图像源。
任何想法?
I have a custom control that makes use of four different images. These images are stored as Assets under the various 'themes', such that the 'Star Theme' which will have four images based on star shapes.
The control has a Theme property, but I would like to extend the concept so that user defined Themes can be created.
I hope to add 'UserDefined' to my Themes enumeration and if this option is selected from the property page then I would like to display four new properties from where the four user defined image sources can be set.
Any ideas?
推荐答案
为此,您必须实现ICustomTypeDescriptor,并且必须创建一个新的PropertyDescriptor,并为Property(属性)提供属性BrowsableAttribute.No。
这样做有点复杂。
我举个例子,遇到麻烦你应该回复......
首先是班级和财产:
For this you have to implement the ICustomTypeDescriptor and you have to create a new PropertyDescriptor with gives the Property (Properties) the Attribute BrowsableAttribute.No.
It is a Little bit complicated to do that.
I give you an example and in case of trouble you should reply ...
At first the class and the Property :
Imports System.ComponentModel
Public Class RMBaseLed
Inherits System.Windows.Forms.Control
Implements ICustomTypeDescriptor
' my Enum
Enum DarstellungAnzeige
Test
Rund
Eckig
AreaSunken
AreaRaised
End Enum
<refreshproperties(refreshproperties.all)>
Property Darstellung As DarstellungAnzeige
Get
Return my_Darstellung
End Get
Set(ByVal value As DarstellungAnzeige)
my_Darstellung = value
Me.Invalidate()
End Set
End Property
Private my_Darstellung As DarstellungAnzeige = DarstellungAnzeige.Rund
end class
现在类中的代码代表ICustomTypeDescriptor和附加代码:
now the code inside the class which represents the ICustomTypeDescriptor and additional code :
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetAttributes() As System.ComponentModel.AttributeCollection Implements System.ComponentModel.ICustomTypeDescriptor.GetAttributes
Return TypeDescriptor.GetAttributes(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetClassName() As String Implements System.ComponentModel.ICustomTypeDescriptor.GetClassName
Return TypeDescriptor.GetClassName(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetComponentNaMe() As String Implements System.ComponentModel.ICustomTypeDescriptor.GetComponentName
Return TypeDescriptor.GetComponentName(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetConverter() As System.ComponentModel.TypeConverter _
Implements System.ComponentModel.ICustomTypeDescriptor.GetConverter
Return TypeDescriptor.GetConverter(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetDefaultEvent() As System.ComponentModel.EventDescriptor _
Implements System.ComponentModel.ICustomTypeDescriptor.GetDefaultEvent
Return TypeDescriptor.GetDefaultEvent(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetDefaultProperty() As System.ComponentModel.PropertyDescriptor _
Implements System.ComponentModel.ICustomTypeDescriptor.GetDefaultProperty
Return TypeDescriptor.GetDefaultProperty(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Function GetEditor(ByVal editorBaseType As System.Type) As Object _
Implements System.ComponentModel.ICustomTypeDescriptor.GetEditor
Return TypeDescriptor.GetEditor(Me, editorBaseType, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Overloads Function GetEvents() As System.ComponentModel.EventDescriptorCollection _
Implements System.ComponentModel.ICustomTypeDescriptor.GetEvents
Return TypeDescriptor.GetEvents(Me, True)
End Function
<Description("Simply delegates to the TypeDescriptor method.")> _
Public Overloads Function GetEvents(ByVal attributes() As System.Attribute) As System.ComponentModel.EventDescriptorCollection _
Implements System.ComponentModel.ICustomTypeDescriptor.GetEvents
Return TypeDescriptor.GetEvents(Me, attributes, True)
End Function
<Description("Returns the wrapped object.")> _
Public Function GetPropertyOwner(ByVal pd As System.ComponentModel.PropertyDescriptor) As Object _
Implements System.ComponentModel.ICustomTypeDescriptor.GetPropertyOwner
Return Me
End Function
<Description("Returns the list of properties as defined in the constructor")> _
Public Overloads Function GetProperties() As System.ComponentModel.PropertyDescriptorCollection _
Implements System.ComponentModel.ICustomTypeDescriptor.GetProperties
Dim pd As PropertyDescriptorCollection = TypeDescriptor.GetProperties(Me, True)
Return FilterProperties(pd)
End Function
<Description("Returns the list of properties as defined in the constructor")> _
Public Overloads Function GetProperties(ByVal attributes() As System.Attribute) As System.ComponentModel.PropertyDescriptorCollection _
Implements System.ComponentModel.ICustomTypeDescriptor.GetProperties
Dim pd As PropertyDescriptorCollection = TypeDescriptor.GetProperties(Me, attributes, True)
Return FilterProperties(pd)
End Function
Private Function FilterProperties(ByVal origProperties As PropertyDescriptorCollection) As PropertyDescriptorCollection
Dim myPD As PropertyDescriptor
Dim myListe As New ArrayList
Dim setHidden As Boolean
For i As Integer = 0 To origProperties.Count - 1
myPD = origProperties.Item(i)
setHidden = False
' depending on the selection of the Enum I make the following Properties visible / unvisible
Select Case myPD.Name
Case "ForeColor"
If Darstellung <> DarstellungAnzeige.Rund _
And Darstellung <> DarstellungAnzeige.Eckig Then setHidden = True
Case "Size"
If Darstellung = DarstellungAnzeige.Rund Then setHidden = True
Case "Diameter"
If Darstellung <> DarstellungAnzeige.Rund Then setHidden = True
End Select
If setHidden Then
myListe.Add(New HiddenPropertyDescriptor(myPD))
Else
myListe.Add(myPD)
End If
Next
Dim myPDListe(myListe.Count - 1) As PropertyDescriptor
myListe.CopyTo(myPDListe)
Return New PropertyDescriptorCollection(myPDListe)
End Function
最后是HiddenPropertyDescriptor:
at last the "HiddenPropertyDescriptor" :
Imports System.ComponentModel
Friend NotInheritable Class HiddenPropertyDescriptor
Inherits PropertyDescriptor
Private myPD As PropertyDescriptor = Nothing
Public Sub New(ByVal pd As PropertyDescriptor)
MyBase.New(pd)
myPD = pd
End Sub
Public Overrides ReadOnly Property Attributes() As AttributeCollection
Get
Return New AttributeCollection(BrowsableAttribute.No)
'Return myPD.Attributes
End Get
End Property
Protected Overrides Sub FillAttributes(ByVal attributeList As IList)
attributeList.Add(BrowsableAttribute.No)
End Sub
Public Overrides ReadOnly Property IsBrowsable As Boolean
Get
Return False
'Return myPD.IsBrowsable
End Get
End Property
Public Overrides ReadOnly Property ComponentType() As Type
Get
Return myPD.ComponentType
End Get
End Property
' The type converter for this property.
' A translator can overwrite with its own converter.
Public Overrides ReadOnly Property Converter() As TypeConverter
Get
Return myPD.Converter
End Get
End Property
' Returns the property editor
' A translator can overwrite with its own editor.
Public Overrides Function GetEditor(ByVal editorBaseType As Type) As Object
Return Me.myPD.GetEditor(editorBaseType)
End Function
' Specifies the property is read only.
Public Overrides ReadOnly Property IsReadOnly() As Boolean
Get
Return myPD.IsReadOnly
End Get
End Property
Public Overrides ReadOnly Property PropertyType() As Type
Get
Return myPD.PropertyType
End Get
End Property
Public Overrides Function CanResetValue(ByVal component As Object) As Boolean
Return myPD.CanResetValue(component)
End Function
Public Overrides Function GetValue(ByVal component As Object) As Object
Return myPD.GetValue(component)
End Function
Public Overrides Sub ResetValue(ByVal component As Object)
myPD.ResetValue(component)
End Sub
Public Overrides Sub SetValue(ByVal component As Object, ByVal val As Object)
myPD.SetValue(component, val)
End Sub
' Determines whether a value should be serialized.
Public Overrides Function ShouldSerializeValue(ByVal component As Object) As Boolean
Return myPD.ShouldSerializeValue(component)
End Function
End Class
$ b $祝你好运...
good luck ...
有趣,但我使用的是Windows Phone 8,找不到ICustomTypeDescriptor或者refreshproperties属性:(有什么建议?
Interesting, but I'm using Windows Phone 8 and can't find ICustomTypeDescriptor or the refreshproperties attribute :( Any suggestions ?
这篇关于在设计时更改可用属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!