Hi,

I'm new here!!!

I just want to ask if is it possible to add a property within a property at VB.Net.

Sample

    Public Class Form1

        Private xproperties As PreferenceProperties

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            xproperties = New PreferenceProperties

            PropertyGrid1.SelectedObject = xproperties
        End Sub

    End Class


    Public Class PreferenceProperties

        Private DBDetails As DatabaseProperties

        Public Sub New()
            DBDetails = New DatabaseProperties
        End Sub

        <Category("Connection")> _
        <Description("")> _
        <DisplayName("Database Properties")> _
        Public Property Database() As DatabaseProperties
            Get
                Return DBDetails
            End Get
            Set(ByVal value As DatabaseProperties)
                DBDetails = value
            End Set
        End Property


    End Class

    Public Class DatabaseProperties
        Private DBHost As String
        Private DBPort As Integer
        Private DBUser As String
        Private DBName As String
        Private DBPass As String

        Public Sub New()
            Me.DBHost = String.Empty
            Me.DBPort = 3306
            Me.DBUser = String.Empty
            Me.DBName = String.Empty
            Me.DBPass = String.Empty
        End Sub

        <Category("Connection")> _
        <Description("Host Name/IP address of the server where the database resides.")> _
        <DefaultValue(GetType(String), "")> _
        <DisplayName("Host Address")> _
        <Browsable(True)> _
        <ReadOnlyAttribute(False)> _
        Public Property HostName() As String
            Get
                Return Me.DBUser
            End Get
            Set(ByVal value As String)
                Me.DBUser = value
            End Set
        End Property


        <Category("Connection")> _
        <Description("The name of the database that you will be connected.")> _
        <DefaultValue(GetType(String), "")> _
        <DisplayName("Database Name")> _
        <Browsable(True)> _
        <ReadOnlyAttribute(False)> _
        Public Property DatabaseName() As String
            Get
                Return Me.DBName
            End Get
            Set(ByVal value As String)
                Me.DBName = value
            End Set
        End Property

        <Category("Connection")> _
        <Description("Port number that the database server is using. The default is 3306.")> _
        <DefaultValue(GetType(Integer), "3306")> _
        <DisplayName("Port Number")> _
        <Browsable(True)> _
        <ReadOnlyAttribute(False)> _
        Public Property PortNumber() As Integer
            Get
                Return Me.DBPort
            End Get
            Set(ByVal value As Integer)
                Me.DBPort = value
            End Set
        End Property



        <Category("Security")> _
        <Description("User name to be use in connecting the server.")> _
        <DefaultValue(GetType(String), "")> _
        <DisplayName("UserName")> _
        <Browsable(True)> _
        <ReadOnlyAttribute(False)> _
        Public Property UserName() As String
            Get
                Return Me.DBUser
            End Get
            Set(ByVal value As String)
                Me.DBUser = value
            End Set
        End Property

        <Category("Security")> _
        <Description("Password to be use in connecting the server.")> _
        <DefaultValue(GetType(String), "")> _
        <DisplayName("Password")> _
        <Browsable(True)> _
        <PasswordPropertyText(True)> _
        <ReadOnlyAttribute(False)> _
        Public Property Password() As String
            Get
                Return Me.DBPass
            End Get
            Set(ByVal value As String)
                Me.DBPass = value
            End Set
        End Property

    End Class

This works when you are in source code, but once you set the property to propertygrid the property becomes readonly.

Can someone help me on this?

Thanks in advance...

Edited 3 Years Ago by shermags: Added a full view of the source code

Comments
A well asked question with supporting info

You need an ExpandableObjectConverter.

It's pretty easy to do. :)

Here is the converter:

Public Class DatabasePropertiesConverter
   Inherits ExpandableObjectConverter

   Public Overrides Function ConvertTo(ByVal context As ITypeDescriptorContext, ByVal culture As Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As Type) As Object

      If destinationType Is GetType(String) Then
         Return "" ' this prevents the type name from showing up in the property grid
      End If

      Return MyBase.ConvertTo(context, culture, value, destinationType)

   End Function
End Class

Now to implement it

   <TypeConverter(GetType(DatabasePropertiesConverter))> _
    Public Class DatabaseProperties
    .
    . <ommitted code>
    .

    'add the NotifyParentPropertyAttribute to each sub property
    <NotifyParentProperty(True)> _
    <Category("Connection")> _
    <Description("Host Name/IP address of the server where the database resides.")> _
    <DefaultValue(GetType(String), "")> _
    <DisplayName("Host Address")> _
    <Browsable(True)> _
    <ReadOnlyAttribute(False)> _
    Public Property HostName() As String
        Get
            Return Me.DBHost
        End Get
        Set(ByVal value As String)
            Me.DBHost = value
        End Set
    End Property

    .  **** I corrected the above property from DBUser to DBHost
    . 
    . <do same for other properties>
    .

Hi TnTinMN,

Thank you for the time you spend with my problem. It really do the trick...

Thanks again.

You are a welcome.

It was nice to see a well defined problem with all the supporting information.

I should have done this last night, but you are getting a up-vote for knowing how to ask for help.

I need a quick answer and to have it I should post a complete information of my question.

Thanks again for the immediate response.

This question has already been answered. Start a new discussion instead.