Freigeben über


Beispiel eines Windows Forms-Designers

In diesem Thema wird ein Designer (HelpLabelDesigner) für das HelpLabel-Extenderprovidersteuerelement beschrieben, das unter Beispiel eines Extenderproviders in Windows Forms beschrieben wird. Der Designer ist eine geschachtelte Klasse im HelpLabel-Steuerelement. Die Möglichkeit zum Downloaden des Quellcodes und eine Demonstration der Verwendung des Beispiels finden Sie im HelpLabel-Beispiel in .NET-Beispiele - Windows Forms: Erstellen von Steuerelementen. Das Designer-Beispiel demonstriert folgende Aspekte:

  • HelpLabelDesigner wird von ControlDesigner abgeleitet.
  • HelpLabelDesigner stellt ein Designerverb bereit, indem die Verbs-Eigenschaft außer Kraft gesetzt wird, die in der IDesigner-Schnittstelle angegeben ist. Zur Entwurfszeit erscheinen Verben als Befehle auf dem Objekt, das mit dem Designer verknüpft ist. Weitere Informationen finden Sie unter Designerverben.
  • HelpLabelDesigner fügt HelpLabel eine Entwurfszeiteigenschaft (TrackSelection) hinzu, indem die PreFilterProperties-Methode außer Kraft gesetzt wird, die von der IDesignerFilter-Schnittstelle angegeben wird. Weitere Informationen zum Hinzufügen oder Ersetzen von Eigenschaften und Ereignissen finden Sie unter Filtern von Metadaten.

Das folgende Codefragment enthält den Code für den Designer.

**Hinweis   **Der folgende Designercode kann allein nicht kompiliert werden. Kompilieren Sie stattdessen das Beispiel im Beispiel eines Extenderproviders in Windows Forms, das den Code für den Designer als geschachtelte Klasse enthält.

      ' <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>
      '
      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 
         ' PreFilterProperties method.  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>
         Private Property TrackSelection() As Boolean
            Get
               Return _trackSelection
            End Get
            Set
               _trackSelection = value
               If _trackSelection Then
                  Dim ss As ISelectionService = CType(GetService(GetType(ISelectionService)), ISelectionService)
                  If Not (ss Is Nothing) Then
                     UpdateHelpLabelSelection(ss)
                  End If
               Else
                  Dim helpLabel As HelpLabel = CType(Control, HelpLabel)
                  If Not (helpLabel.activeControl Is 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 the 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(disposing As Boolean)
          If disposing Then
            Dim ss As ISelectionService = CType(GetService(GetType(ISelectionService)), ISelectionService)
            If Not (ss Is 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(component As IComponent)
            MyBase.Initialize(component)
            
            Dim ss As ISelectionService = CType(GetService(GetType(ISelectionService)), ISelectionService)
            If Not (ss Is Nothing) Then
               AddHandler ss.SelectionChanged, AddressOf OnSelectionChanged
            End If
         End Sub
         
         Private Sub OnSampleVerb(sender As Object, e As EventArgs)
            MessageBox.Show("You have just invoked a sample verb.  Normally, this would do something interesting.")
         End Sub
         
         '
         ' <doc>
         ' <desc>
         '      Our handler for the selection change event.  Here we update the active control within
         '      the help label.
         ' </desc>
         ' </doc>
         '
         Private Sub OnSelectionChanged(sender As Object, e As EventArgs)
            If _trackSelection Then
               Dim ss As ISelectionService = CType(sender, ISelectionService)
               UpdateHelpLabelSelection(ss)
            End If
         End Sub
         
         Protected Overrides Sub PreFilterProperties(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 our help label with the currently active selection.
         ' </summary>
         ' <param name="ss"></param>
         Private Sub UpdateHelpLabelSelection(ss As ISelectionService)
            Dim c As Control = CType(ss.PrimarySelection, Control)
            Dim helpLabel As HelpLabel = CType(Control, HelpLabel)
            If Not (c Is Nothing) Then
               helpLabel.activeControl = c
               helpLabel.Invalidate()
            Else
               If Not (helpLabel.activeControl Is Nothing) Then
                  helpLabel.activeControl = Nothing
                  helpLabel.Invalidate()
               End If
            End If
         End Sub
      End Class
   End Class
[C#]
        //
        // <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>
        //
        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 
      /// PreFilterProperties method.  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>
      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 the 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 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 cannot 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>
            //      The 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 = (Control)ss.PrimarySelection;
        HelpLabel helpLabel = (HelpLabel)Control;
        if (c != null)
        {
          helpLabel.activeControl = c;
          helpLabel.Invalidate();
        }
        else
        {
          if (helpLabel.activeControl != null)
          {
            helpLabel.activeControl = null;
            helpLabel.Invalidate();
          }
        }
      }
        }
    }

Siehe auch

Benutzerdefinierte Designer | Entwurfszeitunterstützung für Windows Forms