Imports System.Drawing.Design
Imports System.ComponentModel
Imports System.Reflection

Namespace ComponentModel
    Public Class ListEditor
        Inherits UITypeEditor

        Public Overloads Overrides Function GetEditStyle(ByVal context As ITypeDescriptorContext) As System.Drawing.Design.UITypeEditorEditStyle
            Return UITypeEditorEditStyle.Modal
        End Function

        'return the same list!
        Public Overloads Overrides Function EditValue(ByVal context As ITypeDescriptorContext, ByVal provider As IServiceProvider, ByVal value As Object) As Object
            Dim a As ListEditorPropertiesAttribute = CType(context.PropertyDescriptor.Attributes(GetType(ListEditorPropertiesAttribute)), ListEditorPropertiesAttribute)

            Dim f As New ListEditorForm(CType(ObjectHelp.GetCopy(value), IList), a.ItemType, a.Title)

            If f.ShowDialog() = DialogResult.OK Then
                Dim list As IList = CType(value, IList)
                list.Clear()

                For Each i As Object In f.lb.Items
                    list.Add(i)
                Next

                Return list
            End If

            Return value
        End Function

        Public Overloads Function EditValue(ByVal list As IList, ByVal o As Object, ByVal propertyName As String) As Object
            Dim pd As PropertyDescriptor = TypeDescriptor.GetProperties(o).Item(propertyName)
            Return EditValue(New Context(pd), Nothing, list)
        End Function

        Public Overloads Function EditValue(ByVal list As IList, ByVal itemType As Type, ByVal title As String) As Object
            Dim pd As PropertyDescriptor = TypeDescriptor.GetProperties( _
                New PropertyObject).Item("ListProperty")

            Dim a As ListEditorPropertiesAttribute = CType(pd.Attributes(GetType(ListEditorPropertiesAttribute)), _
                ListEditorPropertiesAttribute)

            a.ItemType = itemType
            a.Title = title

            Return EditValue(New Context(pd), Nothing, list)
        End Function

        Public Class PropertyObject
            Private ListPropertyValue As IList

            <ListEditorProperties(Nothing, "Collection Editor")> _
            Public Property ListProperty() As IList
                Get
                    Return ListPropertyValue
                End Get
                Set(ByVal Value As IList)
                    ListPropertyValue = Value
                End Set
            End Property
        End Class

        Public Class Context
            Implements ITypeDescriptorContext

            Private PropDesc As PropertyDescriptor

            Public Sub New(ByVal pd As PropertyDescriptor)
                PropDesc = pd
            End Sub

            Public ReadOnly Property Container() As System.ComponentModel.IContainer Implements ITypeDescriptorContext.Container
                Get
                    Return Nothing
                End Get
            End Property

            Public ReadOnly Property Instance() As Object Implements ITypeDescriptorContext.Instance
                Get
                    Return Nothing
                End Get
            End Property

            Public Sub OnComponentChanged() Implements System.ComponentModel.ITypeDescriptorContext.OnComponentChanged
            End Sub

            Public Function OnComponentChanging() As Boolean Implements ITypeDescriptorContext.OnComponentChanging
            End Function

            Public ReadOnly Property PropertyDescriptor() As PropertyDescriptor Implements ITypeDescriptorContext.PropertyDescriptor
                Get
                    Return PropDesc
                End Get
            End Property

            Public Function GetService(ByVal serviceType As Type) As Object Implements IServiceProvider.GetService
                Return Nothing
            End Function
        End Class
    End Class
End Namespace
