Click here to Skip to main content
15,894,297 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a problem opening CollectionEditor from verb. It works fine when editing from property window but when I open the CollectionEditor from verbs, it gives me a non component item after adding a new item.

this is the component item.
CC1.PNG

this is what I get after adding an item from verbs.
CC2.PNG

If you can see, after adding an item, Data and Design sections are missing or the new item is not a component.

What I have tried:

below is my code. Am I missing something? thanks in advance.

Imports System.Drawing.Design
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Windows.Forms.Design

Friend Class NavCollectionControlDesigner
    Inherits ControlDesigner
    Private MyControl As mSideBarPanelNav

    Public Overrides Sub Initialize(Component As IComponent)
        MyBase.Initialize(Component)
        ' Record instance of control we're designing
        MyControl = DirectCast(Component, mSideBarPanelNav)

    End Sub

    Protected Overrides Sub Dispose(disposing As Boolean)
        MyBase.Dispose(disposing)
    End Sub

    Public Overrides ReadOnly Property AssociatedComponents() As System.Collections.ICollection
        Get
            Return MyControl.Items
        End Get
    End Property

    Public Overrides ReadOnly Property Verbs() As System.ComponentModel.Design.DesignerVerbCollection
        Get
            Dim v As New DesignerVerbCollection()

            ' Verb to add Items
            v.Add(New DesignerVerb("&Edit Items", New EventHandler(AddressOf OnAddButton)))

            Return v
        End Get
    End Property

    Private Sub OnAddButton(sender As Object, e As System.EventArgs)
        Dim pd As PropertyDescriptor = TypeDescriptor.GetProperties(MyControl)("Items")
        Dim editor As UITypeEditor = DirectCast(pd.GetEditor(GetType(UITypeEditor)), UITypeEditor)
        Dim serviceProvider As New RuntimeServiceProvider()
        editor.EditValue(serviceProvider, serviceProvider, MyControl.Items)

    End Sub

End Class

Public Class RuntimeServiceProvider
    Implements IServiceProvider
    Implements ITypeDescriptorContext


    Private Function IServiceProvider_GetService(serviceType As Type) As Object Implements IServiceProvider.GetService

        If serviceType = GetType(IWindowsFormsEditorService) Then
            Return New WindowsFormsEditorService()
        End If

        Return Nothing
    End Function

    Private Class WindowsFormsEditorService
        Implements IWindowsFormsEditorService

        Public Sub DropDownControl(control As Control) Implements IWindowsFormsEditorService.DropDownControl
            MsgBox(control.Name)
        End Sub

        Public Sub CloseDropDown() Implements IWindowsFormsEditorService.CloseDropDown
        End Sub

        Public Function ShowDialog(dialog As Form) As System.Windows.Forms.DialogResult Implements IWindowsFormsEditorService.ShowDialog
            dialog.Font = New Font("Segoe UI", 9, FontStyle.Regular)
            Return dialog.ShowDialog()
        End Function

    End Class


    Public Sub OnComponentChanged() Implements ITypeDescriptorContext.OnComponentChanged
        
    End Sub

    Public Function OnComponentChanging() As Boolean Implements ITypeDescriptorContext.OnComponentChanging
        Return ((Not CType(Me, ITypeDescriptorContext).PropertyDescriptor Is Nothing) AndAlso Not CType(Me, ITypeDescriptorContext).PropertyDescriptor.IsReadOnly)
        'Return True
        ' true to keep changes, otherwise false
    End Function

    Public ReadOnly Property Container() As 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 ReadOnly Property PropertyDescriptor() As PropertyDescriptor Implements ITypeDescriptorContext.PropertyDescriptor
        Get
            Return Nothing
        End Get
    End Property

End Class

Public Class Item
    Inherits Component

    'codes not related to the issue
End Class

<Designer(GetType(NavCollectionControlDesigner))>
Public Class mSideBarPanelNav
    Inherits Control

    Private _Items As New ItemsCollection()
    <Category("Item Collections")>
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
    <Editor(GetType(ItemCollectionEditor), GetType(System.Drawing.Design.UITypeEditor))>
    Public ReadOnly Property Items() As ItemsCollection
        Get
            Return _Items
        End Get
    End Property

    'codes not related to the issue
End Class
Posted
Updated 8-May-17 1:02am
v3
Comments
Ralf Meier 8-May-17 2:06am    
Because this code looks complete different to the way I realize it :
You want to edit some of the Properties of your control with the SmartTag-Designer with having the small Triangle-Button at the upper right side of your control ? Here you want to edit the collection-property (too) ?
Ralf Meier 8-May-17 4:53am    
Additional :
Show also the Declaration of your ItemsCollection ..
Ralf Meier 11-May-17 15:20pm    
It would be nice if you give a Feedback to one (or both) Solutions ...

If your ItemsCollection Looks like this it should work like you want :
VB
Public Class ItemCollection
    Inherits CollectionBase

    Public Sub Add(ByVal item As Item)
        List.Add(item)
    End Sub

    Public Property Item(ByVal index As Integer) As Item
        Get
            Return List(index)
        End Get
        Set(ByVal value As Item)
            List(index) = value
        End Set
    End Property

    Protected Overrides Sub OnInsertComplete(ByVal index As Integer, ByVal value As Object)
        Dim item As Item = value

        MyBase.OnInsertComplete(index, item)
    End Sub

    Protected Overrides Sub OnRemoveComplete(ByVal index As Integer, ByVal value As Object)
        Dim item As Item = value

        MyBase.OnRemoveComplete(index, item)
    End Sub

End Class


... but you could also access it in a different way with the SmartTag-Designer ...
 
Share this answer
 
to show you a different way (I replaced and modified your Designer-Class) :
VB
Public Class NavCollectionControlDesigner
    Inherits ControlDesigner

    Private MyControl As mSideBarPanelNav

    Public Overrides Sub Initialize(Component As IComponent)
        MyBase.Initialize(Component)
        ' Record instance of control we're designing
        MyControl = DirectCast(Component, mSideBarPanelNav)

    End Sub

    Protected Overrides Sub Dispose(disposing As Boolean)
        MyBase.Dispose(disposing)
    End Sub

    Private _ActionLists As DesignerActionListCollection

    Public Overrides ReadOnly Property ActionLists As System.ComponentModel.Design.DesignerActionListCollection
        Get
            If _ActionLists Is Nothing Then
                _ActionLists = New DesignerActionListCollection()
                _ActionLists.Add(New NavCollectionControlSmartTags(Me))
            End If
            Return _ActionLists
        End Get
    End Property

End Class

Public Class NavCollectionControlSmartTags
    Inherits DesignerActionList

    Private _Designer As NavCollectionControlDesigner
    Private _ActiveControl As mSideBarPanelNav
    Private _DesignerActionUIService As DesignerActionUIService

    Public Sub New(ByVal designer As NavCollectionControlDesigner)
        MyBase.New(designer.Component)
        _Designer = designer
        MyBase.AutoShow = False 'True= the SmartTag is directly opened if the Control is newly placed
        _ActiveControl = TryCast(designer.Component, mSideBarPanelNav)
        _DesignerActionUIService = DirectCast(Me.GetService(GetType(DesignerActionUIService)), DesignerActionUIService)
    End Sub

    Public Overrides Function GetSortedActionItems() As DesignerActionItemCollection
        Dim Itemlist As New DesignerActionItemCollection()

        If _ActiveControl IsNot Nothing Then
            Itemlist.Add(New DesignerActionHeaderItem("explaining Text", "Own"))
            Itemlist.Add(New DesignerActionPropertyItem("Items_InActionList", "declared Items", "View", PropertyHelper.GetDescription(_ActiveControl, "Items")))
            Itemlist.Add(New DesignerActionPropertyItem("BackColor_InActionList", "BackColor", "Colors", PropertyHelper.GetDescription(_ActiveControl, "BackColor")))
        End If
        Return Itemlist
    End Function



    ReadOnly Property Items_InActionList() As ItemCollection
        Get
            Return _ActiveControl.Items
        End Get
    End Property

    Public Property BackColor_InActionList() As Color
        Get
            Return _ActiveControl.BackColor
        End Get
        Set(ByVal value As Color)
            _ActiveControl.BackColor = value
        End Set
    End Property

End Class
 
Share this answer
 

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