Search code examples
vb.netpropertiesbrowsable

How to create a Browse-able property for class with type dictionary


I created a class that inherits button in win forms How can i create a Browsable property with type dictionary ?

here is my code but i didn't find it in properties menu vb.net

<Browsable(True)>
Property Set_ddn() As Dictionary(Of TextBox, String)
    Get
        Return ddn
    End Get
    Set(ByVal value As Dictionary(Of TextBox, String))
        ddn = value
    End Set
End Property

how can i make it browsable ? or what should i use instead of dictionary?

or another solution


Solution

  • i found the answer here (C#) https://stackoverflow.com/a/42829336/1543991

    rewrite code for vb.net

    You should write your own type descriptor by deriving from CustomTypeDescriptor or implementing ICustomTypeDescriptor. Here is an example:

    MyPropertyDescriptor

    Provide a custom description for a property. Here I override Attributes property to provide a new list of attributes for property. For example I check if the property has [Category("Extra")], I also added a [Browsable(false)] to its attribute collection.

    Imports System
    Imports System.ComponentModel
    Imports System.Linq
    
    Public Class MyPropertyDescriptor
    Inherits PropertyDescriptor
    
    Private o As PropertyDescriptor
    
    Public Sub New(ByVal originalProperty As PropertyDescriptor)
        MyBase.New(originalProperty)
        o = originalProperty
    End Sub
    
    Public Overrides Function CanResetValue(ByVal component As Object) As Boolean
        Return o.CanResetValue(component)
    End Function
    
    Public Overrides Function GetValue(ByVal component As Object) As Object
        Return o.GetValue(component)
    End Function
    
    Public Overrides Sub ResetValue(ByVal component As Object)
        o.ResetValue(component)
    End Sub
    
    Public Overrides Sub SetValue(ByVal component As Object, ByVal value As Object)
        o.SetValue(component, value)
    End Sub
    
    Public Overrides Function ShouldSerializeValue(ByVal component As Object) As Boolean
        Return o.ShouldSerializeValue(component)
    End Function
    
    Public Overrides ReadOnly Property Attributes As AttributeCollection
        Get
            Dim attributes = MyBase.Attributes.Cast(Of Attribute)().ToList()
            Dim category = attributes.OfType(Of CategoryAttribute)().FirstOrDefault()
            If category IsNot Nothing AndAlso category.Category = "Extra" Then attributes.Add(New BrowsableAttribute(False))
            Return New AttributeCollection(attributes.ToArray())
        End Get
    End Property
    
    Public Overrides ReadOnly Property ComponentType As Type
        Get
            Return o.ComponentType
        End Get
    End Property
    
    Public Overrides ReadOnly Property IsReadOnly As Boolean
        Get
            Return o.IsReadOnly
        End Get
    End Property
    
    Public Overrides ReadOnly Property PropertyType As Type
        Get
            Return o.PropertyType
        End Get
    End Property
    End Class
    

    MyTypeDescriptor

    Used to provide a list of custom property descriptors for a type.

    Imports System
    Imports System.ComponentModel
    Imports System.Linq
    
    Public Class MyTypeDescriptor
        Inherits CustomTypeDescriptor
    
        Private original As ICustomTypeDescriptor
    
        Public Sub New(ByVal originalDescriptor As ICustomTypeDescriptor)
            MyBase.New(originalDescriptor)
            original = originalDescriptor
        End Sub
    
        Public Overrides Function GetProperties() As PropertyDescriptorCollection
            Return Me.GetProperties(New Attribute() {})
        End Function
    
        Public Overrides Function GetProperties(ByVal attributes As Attribute()) As PropertyDescriptorCollection
            Dim properties = MyBase.GetProperties(attributes).Cast(Of PropertyDescriptor)().[Select](Function(p) New MyPropertyDescriptor(p)).ToArray()
            Return New PropertyDescriptorCollection(properties)
        End Function
    End Class
    

    MyTypeDescriptionProvider

    Used to connect MyTypeDescriptor to a class using TypeDescriptionProvider attribute.

    Imports System
    Imports System.ComponentModel
    
    Public Class MyTypeDescriptionProvider
        Inherits TypeDescriptionProvider
    
        Public Sub New()
            MyBase.New(TypeDescriptor.GetProvider(GetType(Object)))
        End Sub
    
        Public Overrides Function GetTypeDescriptor(ByVal type As Type, ByVal o As Object) As ICustomTypeDescriptor
            Dim baseDescriptor As ICustomTypeDescriptor = MyBase.GetTypeDescriptor(type, o)
            Return New MyTypeDescriptor(baseDescriptor)
        End Function
    End Class
    

    MySampleClass

    Contains a property decorated with [Category("Extra")]. So Property2 will not be visible in property grid. (In visual studio or collection editor or even run-time property grid)

    <TypeDescriptionProvider(GetType(MyTypeDescriptionProvider))>
    Public Class MySampleClass
        Public Property Property1 As Integer
        <Category("Extra")>
        Public Property Property2 As String
    End Class
    

    MyComplexComponent

    Contains a collection of MySampleClass. So you can see behavior of MySampleClass in collection editor.

    Imports System.Collections.ObjectModel
    Imports System.ComponentModel
    
    Public Class MyComplexComponent
        Inherits Component
    
        Public Sub New()
            MySampleClasses = New Collection(Of MySampleClass)()
        End Sub
    
        <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
        Public Property MySampleClasses As Collection(Of MySampleClass)
    End Class
    

    enter image description here