silver
silver

Reputation: 13

Avoid Initializing New ComponentDesigner in System.Windows.Forms

I'm currently trying to build a non visual Component with its custome Component Designer, and wonder if there is any way to detect if the component already added to the design surface (i.e Form) and also how to force the component not added itself again in Design Time, here is what i did so far.

Public Class TestComponentDesigner
Inherits ComponentDesigner


Private Sub DoNotAllowInitializingNewComponent()
    Dim testComp As TestComponent = CType(MyBase.Component, TestComponent)
    Dim host As IDesignerHost = TryCast(testComp.Site.GetService(GetType(IDesignerHost)), IDesignerHost)
    Dim testComponentType As Type = GetType(TestComponent)
    If host IsNot Nothing AndAlso host.Container Is testComp.Owner Then
        Dim designer As ComponentDesigner = TryCast(host.GetDesigner(testComp.Owner), ComponentDesigner)
        If designer IsNot Nothing Then

            ' The Problem ?????????????????????????????????????????????????????????
            ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

            ' get the owner associated component collection
            For Each currentComponent As IComponent In designer.AssociatedComponents
                If currentComponent.Site IsNot Nothing Then
                    ' Allow to Add a new session of Test Component
                    ' Example Only
                    ' ?????????????????????????????
                    testComp.Owner.AllowDrop = False
                Else
                    ' Do not allow to added a new session of TestComponent
                    ' Example Only
                    ' ?????????????????????????????
                    testComp.Owner.AllowDrop = True
                End If

            Next

            ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

        End If
    End If
End Sub

End Class

Upvotes: 0

Views: 150

Answers (1)

Hans Passant
Hans Passant

Reputation: 941635

Using a designer to enforce this rule is the wrong way to go about it. It is not that you can't do it, just iterate the IDesignerHost.Container.Components collection and count the number of components that are of the type of your class. And throw an exception when you are unhappy. For example:

Public Overrides Sub InitializeNewComponent(defaultValues As IDictionary)
    Dim testComp = DirectCast(MyBase.Component, TestComponent)
    Dim host = DirectCast(Me.GetService(GetType(IDesignerHost)), IDesignerHost)
    Dim count = 0
    For Each comp As Component In host.Container.Components
        If comp.GetType() = GetType(TestComponent) Then
            count += 1
            If count > 1 then Throw New Exception("Sorry, only one TestComponent permitted")
        End If
    Next
    MyBase.InitializeNewComponent(defaultValues)
End Sub

But the message the programmer sees is very ugly. You should get involved earlier and prevent the component instance from being created in the first place. You need your own ToolBoxItem so you can display your own message and simply not create the component in an overload for the CreateComponentsCore() method.

No need for me to show you how to do this, the MSDN article for ToolBoxItem already has all the code you need for that.

Upvotes: 1

Related Questions