Gdno Ответов: 1

Сохраняйте коллекцию во время разработки


Привет,
Я создаю компонент, который я называю CustomerComponent, этот компонент имеет только одно свойство Customers, которое получает коллекцию из моего класса Customer. Я пытаюсь создать форму для редактирования этой коллекции во время разработки через UITypeEditor. Однако значения, добавленные во время разработки, не отражаются в файле .Designer, то есть значения не сохраняются. Пожалуйста, помогите мне сделать это. Ниже мой код и в конце концов мое решение для загрузки.

Вот код для моего класса CustomerComponent:

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


Вот код формы, используемый в UITypeEditor:

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


Ссылка на решение
Скачать Решение[^]

Что я уже пробовал:

Я попытался наследовать класс CollectionBase в классе Customers, и в этом случае добавленные значения отражаются в файле .Designer, но с синтаксической ошибкой.

1 Ответов

Рейтинг:
10

Ralf Meier

Я немного изменил ваш (Для меня релевантный) код, чтобы заставить его работать. Я думаю, что это поможет вам :

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


Gdno

Теперь, когда я добавляю нового клиента во время разработки, этот клиент автоматически записывается в файл .Designer, однако если я открою файл .Designer, чтобы увидеть сгенерированный код, а затем вернусь и попытаюсь добавить еще клиентов, они перестанут записываться в файл .Designer.

Ralf Meier

Да ... конечно.
Разве это не то, что ты хочешь иметь? ..
Я не понимаю вашей проблемы в данный момент - для меня это работает должным образом ... но я не пользовался вашим редактором (для меня это не имело смысла) ...

Gdno

Я хочу, чтобы даже если я открою файл .Designer, я смогу добавить новых клиентов в свой компонент во время разработки. Потому что добавление клиентов работает только до тех пор, пока я не открою файл .Designer и не увижу код, который был сгенерирован автоматически. Если я сделаю это один раз, то клиенты, добавленные после этого, и только те, которые были добавлены после этого, не будут сохраняться при запуске приложения.

Gdno

Только комментарий к тому, что вы сказали редактору, не имеет смысла. Без редактора, как я могу редактировать коллекцию во время разработки?

Ralf Meier

Попробуйте код, как я его разместил. .Net имеет свой собственный CollectionEditor, который работает, если вы нажмете внутри PropertyGrid на вашем Customers-Property.
Но позже я посмотрю на вашего редактора, чтобы понять, что с ним не так. Но как я уже писал раньше - с коллекционным редактором из .Чистая она работает исправно ...

Gdno

Я создавал редакторскую форму без необходимости. Я сделал то, что вы сказали, и это сработало прекрасно. Большое спасибо за Вашу поддержку и терпение.

Ralf Meier

Отлично... пожалуйста...
И спасибо за Ваш голос :)

BillWoodruff

+5 Отличная работа, Ральф

Ralf Meier

Спасибо, Билл.