共用方式為


HOW TO:實作控制項的設計工具

這個主題將描述如何針對 HOW TO:實作 HelpLabel 擴充性提供者中所述的 HelpLabel 擴充性提供者控制項來實作設計工具 (HelpLabelDesigner)。 設計工具是 HelpLabel 控制項中的巢狀類別。 此設計工具程式碼範例將示範下列各個要點:

  • HelpLabelDesigner 是衍生自 ControlDesigner

  • HelpLabelDesigner 會提供設計工具動詞命令,透過的方法是覆寫 IDesigner 介面中指定的 Verbs 屬性。 在設計階段時,動詞命令將成為與設計工具相關聯的物件命令。 如需詳細資訊,請參閱設計工具動詞命令

  • HelpLabelDesigner 會將設計階段屬性 (TrackSelection) 加入到 HelpLabel,透過的方法是覆寫 IDesignerFilter 介面所指定的 PreFilterProperties 方法。 如需加入或取代屬性和事件的詳細資訊,請參閱中繼資料篩選

範例

下列程式碼範例含有設計工具的程式碼。

注意事項注意事項

下列設計工具程式碼將不會自行編譯, 而是會編譯 HOW TO:實作 HelpLabel 擴充性提供者中的範例,其中包含了當做巢狀類別的設計工具之程式碼。

'
' <doc>
' <desc>
'      This is a designer for the HelpLabel.  This designer provides
'      design time feedback for the label.  The help label responds
'      to changes in the active control, but these events do not
'      occur at design time.  In order to provide some usable feedback
'      that the control is working the right way, this designer listens
'      to selection change events and uses those events to trigger active
'      control changes.
' </desc>
' </doc>
'
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
Public Class HelpLabelDesigner
    Inherits System.Windows.Forms.Design.ControlDesigner

    Private _trackSelection As Boolean = True

    ' <summary>
    ' This property is added to the control's set of properties in the method
    ' PreFilterProperties below.  Note that on designers, properties that are
    ' explictly declared by TypeDescriptor.CreateProperty can be declared as
    ' private on the designer.  This helps to keep the designer's public
    ' object model clean.
    ' </summary>
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
    Private Property TrackSelection() As Boolean
        Get
            Return _trackSelection
        End Get
        Set(ByVal Value As Boolean)
            _trackSelection = Value
            If _trackSelection Then
                Dim ss As ISelectionService = CType(GetService(GetType(ISelectionService)), ISelectionService)
                If (ss IsNot Nothing) Then
                    UpdateHelpLabelSelection(ss)
                End If
            Else
                Dim helpLabel As HelpLabel = CType(Control, HelpLabel)
                If (helpLabel.activeControl IsNot Nothing) Then
                    helpLabel.activeControl = Nothing
                    helpLabel.Invalidate()
                End If
            End If
        End Set
    End Property

    Public Overrides ReadOnly Property Verbs() As DesignerVerbCollection
        Get
            Dim myVerbs() As DesignerVerb = {New DesignerVerb("Sample Verb", AddressOf OnSampleVerb)}
            Return New DesignerVerbCollection(myVerbs)
        End Get
    End Property

    '
    ' <doc>
    ' <desc>
    '      Overrides Dispose.  Here we remove our handler for the selection changed
    '      event.  With designers, it is critical that they clean up any events they
    '      have attached.  Otherwise, during the course of an editing session many
    '      designers might get created and never destroyed.
    ' </desc>
    ' </doc>
    '
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            Dim ss As ISelectionService = CType(GetService(GetType(ISelectionService)), ISelectionService)
            If (ss IsNot Nothing) Then
                RemoveHandler ss.SelectionChanged, AddressOf OnSelectionChanged
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    '
    ' <doc>
    ' <desc>
    '       Overrides initialize.  Here we add an event handler to the selection service.
    '      Notice that we are very careful not to assume that the selection service is
    '      available.  It is entirely optional that a service is available and you should
    '      always degrade gracefully if a service cannot be found.
    ' </desc>
    ' </doc>
    '
    Public Overrides Sub Initialize(ByVal component As IComponent)
        MyBase.Initialize(component)

        Dim ss As ISelectionService = CType(GetService(GetType(ISelectionService)), ISelectionService)
        If (ss IsNot Nothing) Then
            AddHandler ss.SelectionChanged, AddressOf OnSelectionChanged
        End If
    End Sub

    Private Sub OnSampleVerb(ByVal sender As Object, ByVal e As EventArgs)
        MessageBox.Show("You have just invoked a sample verb.  Normally, this would do something interesting.")
    End Sub

    '
    ' <doc>
    ' <desc>
    '      The handler for the selection change event.  Here we update the active control within
    '      the help label.
    ' </desc>
    ' </doc>
    '
    Private Sub OnSelectionChanged(ByVal sender As Object, ByVal e As EventArgs)
        If _trackSelection Then
            Dim ss As ISelectionService = CType(sender, ISelectionService)
            UpdateHelpLabelSelection(ss)
        End If
    End Sub

    Protected Overrides Sub PreFilterProperties(ByVal properties As IDictionary)
        ' Always call base first in PreFilter* methods, and last in PostFilter*
        ' methods.
        MyBase.PreFilterProperties(properties)

        ' We add a design-time property called TrackSelection that is used to track
        ' the active selection.  If the user sets this to true (the default), then
        ' we will listen to selection change events and update the control's active
        ' control to point to the current primary selection.
        properties("TrackSelection") = TypeDescriptor.CreateProperty( _
           Me.GetType(), _
           "TrackSelection", _
           GetType(Boolean), _
           New Attribute() {CategoryAttribute.Design})
    End Sub

    ' <summary>
    ' This is a helper method that, given a selection service, will update the active control
    ' of the help label with the currently active selection.
    ' </summary>
    ' <param name="ss"></param>
    Private Sub UpdateHelpLabelSelection(ByVal ss As ISelectionService)
        Dim c As Control = CType(ss.PrimarySelection, Control)
        Dim helpLabel As HelpLabel = CType(Control, HelpLabel)
        If (c IsNot Nothing) Then
            helpLabel.activeControl = c
            helpLabel.Invalidate()
        Else
            If (helpLabel.activeControl IsNot Nothing) Then
                helpLabel.activeControl = Nothing
                helpLabel.Invalidate()
            End If
        End If
    End Sub

    Public Sub New()

    End Sub
End Class
        //
        // <doc>
        // <desc>
        //      This is a designer for the HelpLabel.  This designer provides
        //      design time feedback for the label.  The help label responds
        //      to changes in the active control, but these events do not
        //      occur at design time.  In order to provide some usable feedback
        //      that the control is working the right way, this designer listens
        //      to selection change events and uses those events to trigger active
        //      control changes.
        // </desc>
        // </doc>
        //
        [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] 
        public class HelpLabelDesigner : System.Windows.Forms.Design.ControlDesigner 
        {

            private bool trackSelection = true;

            /// <summary>
            /// This property is added to the control's set of properties in the method
            /// PreFilterProperties below.  Note that on designers, properties that are
            /// explictly declared by TypeDescriptor.CreateProperty can be declared as
            /// private on the designer.  This helps to keep the designer's publi
            /// object model clean.
            /// </summary>
            [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden )]
            private bool TrackSelection
            {
                get
                {
                    return trackSelection;
                }
                set
                {
                    trackSelection = value;
                    if (trackSelection)
                    {
                        ISelectionService ss = (ISelectionService)GetService(typeof(ISelectionService));
                        if (ss != null)
                        {
                            UpdateHelpLabelSelection(ss);
                        }
                    }
                    else
                    {
                        HelpLabel helpLabel = (HelpLabel)Control;
                        if (helpLabel.activeControl != null)
                        {
                            helpLabel.activeControl = null;
                            helpLabel.Invalidate();
                        }
                    }
                }
            }

            public override DesignerVerbCollection Verbs
            {
                get
                {
                    DesignerVerb[] verbs = new DesignerVerb[] {
                                                                  new DesignerVerb("Sample Verb", new EventHandler(OnSampleVerb))
                                                              };
                    return new DesignerVerbCollection(verbs);
                }
            }

            //
            // <doc>
            // <desc>
            //      Overrides Dispose.  Here we remove our handler for the selection changed
            //      event.  With designers, it is critical that they clean up any events they
            //      have attached.  Otherwise, during the course of an editing session many
            //      designers may get created and never destroyed.
            // </desc>
            // </doc>
            //
            protected override void Dispose(bool disposing) 
            {
                if (disposing) 
                {
                    ISelectionService ss = (ISelectionService)GetService(typeof(ISelectionService));
                    if (ss != null) 
                    {
                        ss.SelectionChanged -= new EventHandler(OnSelectionChanged);
                    }
                }

                base.Dispose(disposing);
            }

            //
            // <doc>
            // <desc>
            //       Overrides initialize.  Here we add an event handler to the selection service.
            //      Notice that we are very careful not to assume that the selection service is
            //      available.  It is entirely optional that a service is available and you should
            //      always degrade gracefully if a service could not be found.
            // </desc>
            // </doc>
            //
            public override void Initialize(IComponent component) 
            {
                base.Initialize(component);

                ISelectionService ss = (ISelectionService)GetService(typeof(ISelectionService));
                if (ss != null) 
                {
                    ss.SelectionChanged += new EventHandler(OnSelectionChanged);
                }
            }

            private void OnSampleVerb(object sender, EventArgs e)
            {
                MessageBox.Show("You have just invoked a sample verb.  Normally, this would do something interesting.");
            }

            //
            // <doc>
            // <desc>
            //      Our handler for the selection change event.  Here we update the active control within
            //      the help label.
            // </desc>
            // </doc>
            //
            private void OnSelectionChanged(object sender, EventArgs e) 
            {
                if (trackSelection)
                {
                    ISelectionService ss = (ISelectionService)sender;
                    UpdateHelpLabelSelection(ss);
                }
            }

            protected override void PreFilterProperties(IDictionary properties)
            {
                // Always call base first in PreFilter* methods, and last in PostFilter*
                // methods.
                base.PreFilterProperties(properties);

                // We add a design-time property called "TrackSelection" that is used to track
                // the active selection.  If the user sets this to true (the default), then
                // we will listen to selection change events and update the control's active
                // control to point to the current primary selection.
                properties["TrackSelection"] = TypeDescriptor.CreateProperty(
                    this.GetType(),        // the type this property is defined on
                    "TrackSelection",    // the name of the property
                    typeof(bool),        // the type of the property
                    new Attribute[] {CategoryAttribute.Design});    // attributes
            }

            /// <summary>
            /// This is a helper method that, given a selection service, will update the active control
            /// of our help label with the currently active selection.
            /// </summary>
            /// <param name="ss"></param>
            private void UpdateHelpLabelSelection(ISelectionService ss)
            {
                Control c = ss.PrimarySelection as Control;
                HelpLabel helpLabel = (HelpLabel)Control;
                if (c != null)
                {
                    helpLabel.activeControl = c;
                    helpLabel.Invalidate();
                }
                else
                {
                    if (helpLabel.activeControl != null)
                    {
                        helpLabel.activeControl = null;
                        helpLabel.Invalidate();
                    }
                }
            }
        }

請參閱

工作

HOW TO:實作 HelpLabel 擴充性提供者

其他資源

自訂設計工具

擴充設計階段支援