Click here to Skip to main content
15,886,067 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello,
Im creating a component that I call CustomerComponent, this component has only one property called Customers that receives a collection from my Customer class. Im trying to create a Form to edit this collection at design time through UITypeEditor. However, the values ​​added at design time do not reflect in the .Designer file, that is, the values ​​do not persist. Please help me make this work. Below my code and in the end my solution to download.

Here is the code for my CustomerComponent class:

VB
Public Class CustomerComponent
    Inherits Component
    Public Property Customers As New Customers
End Class

Public Class Customer
    Public Property Name As String
    Public Property Age As Integer
End Class

<Editor(GetType(Customers.CustomersEditor), GetType(UITypeEditor))>
Public Class Customers

    Private List As New List(Of Customer)

    Public Function Add(ByVal Item As Customer) As Customer
        List.Add(Item)
        Return Item
    End Function

    Public Function Add(ByVal Name As String, ByVal Age As Integer) As Customer
        Dim Item As New Customer With {
            .Name = Name,
            .Age = Age
        }
        List.Add(Item)
        Return Item
    End Function

    Public Sub AddRange(ByVal Items() As Customer)
        Dim Item As Object
        For Each Item In Items
            List.Add(Item)
        Next
    End Sub

    Default Public ReadOnly Property Item(ByVal Index As Integer) As Customer
        Get
            Return CType(List(Index), Customer)
        End Get
    End Property

    Public Function Count() As Integer
        Return List.Count
    End Function

    Public Sub Clear()
        List.Clear()
    End Sub

    Public Overrides Function ToString() As String
        Return Nothing
    End Function

    Class CustomersEditor
        Inherits UITypeEditor
        Public Overrides Function GetEditStyle(ByVal context As ITypeDescriptorContext) As UITypeEditorEditStyle
            Return UITypeEditorEditStyle.Modal
        End Function

        Public Overrides Function EditValue(ByVal context As ITypeDescriptorContext, ByVal provider As System.IServiceProvider, ByVal value As Object) As Object
            Dim svc As IWindowsFormsEditorService = TryCast(provider.GetService(GetType(IWindowsFormsEditorService)), IWindowsFormsEditorService)
            Dim foo As Customers = TryCast(value, Customers)
            If svc IsNot Nothing AndAlso foo IsNot Nothing Then
                Using form As FormEditor = New FormEditor()
                    form.OtherFields = foo
                    If svc.ShowDialog(form) = DialogResult.OK Then
                        foo = form.OtherFields
                    End If
                End Using
            End If
            Return value
        End Function
    End Class
End Class


Here the form code used in UITypeEditor:

VB
Public Class FormEditor
    Public Customers As New Customers
    Private Customer As Customer

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        Customer = New Customer With {.Name = "Unknown Name"}
        PropertyGrid1.SelectedObject = Customer
        ListBox1.Items.Add(Cust.Name)
        Customers.Add(Customer)
    End Sub

    Private Sub FormEditor_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
        For i = 0 To Customers.Count - 1
            ListBox1.Items.Add(Customers(i).Name)
        Next i
    End Sub
End Class


Link to the solution
Download Solution[^]

What I have tried:

I tried to inherit the CollectionBase class in the Customers class, in which case the added values ​​are reflected in the .Designer file but with a syntax error.
Posted
Updated 21-Feb-19 9:06am
v2

1 solution

I modified your (for me relevant) Code a little bit to make it work. I think that will help you :
VB
Imports System.Windows.Forms.Design
Imports System.ComponentModel

Public Class CustomerComponent
    Inherits Component

    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
    Public ReadOnly Property Customers As Customers
        Get
            Return myCustomers
        End Get
    End Property
    Private myCustomers As New Customers

End Class

Public Class Customer
    Public Property Name As String
    Public Property Age As Integer
End Class

Public Class Customers
    Inherits CollectionBase

    Public Function Add(ByVal Item As Customer) As Customer
        List.Add(Item)
        Return Item
    End Function

    Public Function Add(ByVal Name As String, ByVal Age As Integer) As Customer
        Dim Item As New Customer With {
            .Name = Name,
            .Age = Age
        }
        List.Add(Item)
        Return Item
    End Function

    Public Sub AddRange(ByVal Items() As Customer)
        Dim Item As Object
        For Each Item In Items
            List.Add(Item)
        Next
    End Sub

    Default Public ReadOnly Property Item(ByVal Index As Integer) As Customer
        Get
            Return CType(List(Index), Customer)
        End Get
    End Property

    'Public Function Count() As Integer
    '    Return List.Count
    'End Function

    'Public Sub Clear()
    '    List.Clear()
    'End Sub

    Public Overrides Function ToString() As String
        Return Nothing
    End Function

End Class
 
Share this answer
 
Comments
Gdno 21-Feb-19 15:41pm    
Now when I add a new Customer at design time, that customer is automatically written to the .Designer file, however if I open the .Designer to see the generated code and then come back and try to add more Customers they stop being written in .Designer.
Ralf Meier 22-Feb-19 1:20am    
Yes ... of course.
Isn't that the thing you want to have ...?
I don't understand your problem at the moment - for me it works properly ... but I don't have used your Editor (it made no sense for me) ...
Gdno 22-Feb-19 6:48am    
What I want is that even if I open the .Designer file I can add new Customers to my component at design time. Because adding customers only works until I open the .Designer file and see the code that was generated automatically. If I do this once it is, the Customers added after that, and only the ones that were added after that, will not persist when I run the application.
Gdno 22-Feb-19 7:04am    
Only a comment on what you said to the Editor does not make sense. Without the Editor, how do I edit the collection at design time?
Ralf Meier 22-Feb-19 8:46am    
Try the code like I have posted it. .Net has it own CollectionEditor which is working if you click inside the PropertyGrid on your Customers-Property.
But later I will take a look on your Editor to see what is wrong with it. But as I wrote before - with the CollectionEditor from .Net it works properly ...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900