如何:实现控件的设计器

本主题描述如何为 如何:实现 HelpLabel 扩展程序提供程序 中所述的 HelpLabel 扩展程序提供程序控件实现设计器 (HelpLabelDesigner)。 该设计器是 HelpLabel 控件中的一个嵌套类。 设计器代码示例说明以下要点:

  • HelpLabelDesigner 派生自 ControlDesigner

  • HelpLabelDesigner 通过重写在 IDesigner 接口中指定的 Verbs 属性提供一个设计器谓词。 在设计时,谓词显示为与该设计器相关联的对象上的命令。 有关更多信息,请参见 设计器谓词

  • HelpLabelDesigner 通过重写由 IDesignerFilter 接口指定的 PreFilterProperties 方法将一个设计时属性 (TrackSelection) 添加到 HelpLabel。 有关添加或替换属性和事件的更多信息,请参见 元数据筛选

示例

下面的代码示例包含该设计器的代码。

提示

下面的设计器代码本身不能编译。 相反,应编译 如何:实现 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 扩展程序提供程序

其他资源

自定义设计器

扩展设计时支持