共用方式為


如何:實作控制項的設計工具

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

  • HelpLabelDesigner 是衍生自 ControlDesigner

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

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

範例

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

注意事項注意事項

下列設計工具程式碼將不會自行編譯,而是會編譯 如何:實作 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();
                    }
                }
            }
        }

請參閱

工作

如何:實作 HelpLabel 擴充性提供者

其他資源

自訂設計工具

擴充設計階段支援