Share via


방법: 컨트롤에 대한 디자이너 구현

이 항목에서는 방법: HelpLabel Extender 공급자 구현에 설명되어 있는 HelpLabel Extender 제공자 컨트롤에 대해 디자이너(HelpLabelDesigner)를 구현하는 방법에 대해 설명합니다. 이 디자이너는 HelpLabel 컨트롤의 중첩 클래스입니다. 디자이너 코드 예제에서는 다음 사항을 보여 줍니다.

  • HelpLabelDesigner는 ControlDesigner에서 파생됩니다.

  • HelpLabelDesigner에서는 IDesigner 인터페이스에 지정된 Verbs 속성을 재정의하여 디자이너 동사를 제공합니다. 동사는 디자인 타임에 해당 디자이너와 연관된 개체에 명령으로 나타납니다. 자세한 내용은 디자이너 동사를 참조하십시오.

  • HelpLabelDesigner는 IDesignerFilter 인터페이스에서 지정하는 PreFilterProperties 메서드를 재정의하여 HelpLabel에 디자인 타임 속성(TrackSelection)을 추가합니다. 속성과 이벤트 추가 또는 대체에 대한 자세한 내용은 메타데이터 필터링을 참조하십시오.

예제

다음 코드 예제에는 디자이너에 대한 코드가 포함되어 있습니다.

참고

다음의 디자이너 코드는 자동으로 컴파일되지 않습니다.대신 디자이너에 대한 코드가 중첩된 클래스로 포함되어 있는 방법: HelpLabel Extender 공급자 구현의 예제를 컴파일합니다.

' 
' <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 Extender 공급자 구현

기타 리소스

사용자 지정 디자이너

디자인 타임 지원 확장