Add DesignerVerb on UserControl's Properties

后端 未结 2 2085
星月不相逢
星月不相逢 2020-12-18 16:22

EDIT: After I found what I was really looking for, I edited my initial question so to describe better what I finaly wanted to do.

I am working on a <

2条回答
  •  既然无缘
    2020-12-18 16:57

    You do not necessarily need to create a custom designer to access the various designer services exposed by the WinForm design environment. All you need is an instance of a IServiceProvider Interface. All classes that have System.ComponentModel.Component in their ancestry expose the Site Property. The Site Property is an instance of type ISite that itself inherits from IServiceProvider.

    Most of the design services are defined by the interfaces documented in the System.ComponentModel.Design Namespace. Others like the BehaviorService Class are buried in the documentation and have to be specifically sought out.

    Using a proper designer class has its advantages in that it automatically integrates into the design model and encapsulates that functionality. The technique shown below has the drawback of needing to know the proper time that services are accessible. The first temporal criteria is that the host designer has finished loading. This is achieved by using a combination the host's IsLoaded property and LoadComplete events. The second is knowing when the host is finished adding your component to the design surface. The setting of the Site Property is part of design transaction. When this transaction is completed, the component's designer is accessible. For this, you use the host's TransactionClosed Event.

    With that stated, the entry point is to override the inherited Site Property so that you can gain access to the service provider. This example gains references to the designer host, its selection service, and the controls default designer. The default designer allows you to add a DesignerVerb to its Verb collection.

    Imports System.ComponentModel
    Imports System.ComponentModel.Design
    
    Public Class DemoControl : Inherits Control
        Public Sub New()
            MyBase.New()
            BackColor = Color.Red ' just so we can see it
        End Sub
    
    #Region "Designer Services"
        Private designerHost As Design.IDesignerHost
        Private myDesigner As Design.IDesigner
        Private designerSelectionService As Design.ISelectionService
        Private Shared customDesignerVerb1 As Design.DesignerVerb
    
        Public Overrides Property Site As ISite
            Get
                Return MyBase.Site
            End Get
            Set(value As ISite)
                MyBase.Site = value
                If value Is Nothing Then ' being removed from the design surface
                    DetachDesignerServices()
                Else ' being added to the design surface
                    designerHost = CType(value.GetService(GetType(Design.IDesignerHost)), Design.IDesignerHost)
                    If designerHost IsNot Nothing Then
                        If designerHost.Loading Then
                            ' the designer has not finished loading, 
                            ' postpone all other connections until it has finished loading
                            AddHandler designerHost.LoadComplete, AddressOf DesignerHostLoaded
                        Else
                            ' designerHost loaded, but is in the in the process of creating this instance
                            If designerHost.InTransaction Then
                                AddHandler designerHost.TransactionClosed, AddressOf DesignerTransactionClosed
                            Else
                                AttachDesignerServices()
                            End If
                        End If
                    End If
                End If
            End Set
        End Property
    
        Private Sub DesignerHostLoaded(sender As Object, e As EventArgs)
            RemoveHandler designerHost.LoadComplete, AddressOf DesignerHostLoaded
            AttachDesignerServices()
        End Sub
    
        Private Sub DesignerTransactionClosed(sender As Object, e As DesignerTransactionCloseEventArgs)
            RemoveHandler designerHost.TransactionClosed, AddressOf DesignerTransactionClosed
            AttachDesignerServices()
        End Sub
    
        Private Sub AttachDesignerServices()
            myDesigner = designerHost.GetDesigner(Me)
            If customDesignerVerb1 Is Nothing Then
                customDesignerVerb1 = New Design.DesignerVerb("Verb1", AddressOf DesignerVerb1EventHandler)
            End If
            If myDesigner IsNot Nothing AndAlso
                Not myDesigner.Verbs.Contains(customDesignerVerb1) Then
                myDesigner.Verbs.Add(customDesignerVerb1)
            End If
    
            designerSelectionService = CType(designerHost.GetService(GetType(Design.ISelectionService)), Design.ISelectionService)
            If designerSelectionService IsNot Nothing Then
                AddHandler designerSelectionService.SelectionChanged, AddressOf DesignerSelectionChanged
            End If
        End Sub
    
        Private Sub DetachDesignerServices()
            If designerSelectionService IsNot Nothing Then
                RemoveHandler designerSelectionService.SelectionChanged, AddressOf DesignerSelectionChanged
                designerSelectionService = Nothing
            End If
            If designerHost IsNot Nothing Then
                RemoveHandler designerHost.LoadComplete, AddressOf DesignerHostLoaded
                designerHost = Nothing
            End If
            If myDesigner IsNot Nothing Then
                myDesigner = Nothing
            End If
        End Sub
    
        Private Sub DesignerSelectionChanged(sender As Object, e As EventArgs)
            Static shownCount As Int32
            If designerSelectionService.GetComponentSelected(Me) AndAlso shownCount < 2 Then
                MessageBox.Show("I've been selected." & If(shownCount = 0, "  This will show one more time on selecting.", ""))
                shownCount += 1
            End If
        End Sub
    
        Private Sub DesignerVerb1EventHandler(sender As Object, e As EventArgs)
            MessageBox.Show("Verb1 Cicked")
        End Sub
    
    #End Region ' "Designer Services
    
    End Class
    

提交回复
热议问题