Esempio della finestra di progettazione di Windows Form

In questo argomento viene descritta la finestra di progettazione HelpLabelDesigner per il controllo del provider di estensione HelpLabel descritto in Esempio di provider di estensione di Windows Form. La finestra di progettazione è una classe nidificata nel controllo HelpLabel. Per scaricare il codice sorgente ed esaminare la modalità d'uso dell'esempio, vedere l'esempio HelpLabel in Esempi di .NET - Windows Form: Creazione di controlli. Nell'esempio della finestra di progettazione vengono illustrati i punti indicati di seguito.

  • HelpLabelDesigner deriva da ControlDesigner.
  • HelpLabelDesigner fornisce un verbo di progettazione eseguendo l'override della proprietà Verbs specificata nell'interfaccia IDesigner. In fase di progettazione i verbi appaiono come comandi sull'oggetto che è associato alla finestra di progettazione. Per ulteriori informazioni, vedere Verbi di progettazione.
  • HelpLabelDesigner aggiunge una proprietà in fase di progettazione (TrackSelection) a HelpLabel eseguendo l'override del metodo PreFilterPropeties specificato dall'interfaccia IDesignerFilter. Per ulteriori informazioni sull'aggiunta o sostituzione di proprietà ed eventi, vedere Filtro di metadati.

Nel frammento di codice seguente è contenuto il codice per la finestra di progettazione.

**Nota   **Si noti che il seguente codice della finestra di progettazione da solo non potrà essere compilato. Compilare invece l'esempio in Esempio di provider di estensione di Windows Form, che contiene il codice per la finestra di progettazione come classe nidificata.

      ' <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();
          }
        }
      }
        }
    }

Vedere anche

Finestre di progettazione personalizzate | Supporto in fase di progettazione per Windows Form