2011-12-16 16 views
6

La mia impostazione: Ho un'applicazione C# (.NET 3.5) in Visual Studio 2008. Nessuna possibilità di passare a WPF o qualsiasi cosa :).Abilitare un pulsante per fare clic in fase di progettazione in Visual Studio?

La mia app contiene un controllo personalizzato (una classe pulsante derivata da Windows.Forms.Button) che funge da sostituto per Windows.Forms.TabControl. Posso associare questi pulsanti l'uno con l'altro e ogni pulsante può essere associato a un controllo con cui ha a che fare (di solito una sorta di Windows.Forms.Panel). Sembra qualcosa di simile:

public class TabButton : System.Windows.Forms.Button 
{ 
    // ... 
    protected override void OnClick(EventArgs e) 
    { 
     base.OnClick(e); 
     this.myAssociatedControl.Visible = true; 
     this.tellMyBuddiesToHideTheirControls(); 
    } 
    // ... 
} 

Fondamentalmente si tratta solo di clic su un pulsante, che mostra il suo controllo associato e avendo i controlli associati ai tasti associati scompaiono - proprio come il TabControl, ma l'approccio è facilmente progettabile e io può posizionare i pulsanti lontano dai rispettivi pannelli di contenuto.

Il problema: Questo funziona abbastanza bene in fase di esecuzione, ma l'utilizzo in fase di progettazione è probabilmente strano: Con il mouse, trovare un thats di controllo appartenenti al gruppo ed eseguire una serie di <Send To Back> s fino a quando il il controllo desiderato è visibile.

La domanda: C'è un modo per dire al progettista VS per valutare i clic sui pulsanti in fase di progettazione come fa con TabControl in modo che possa cambiare le schede semplicemente cliccando loro come farei a tempo di esecuzione?

Ho cercato per un po 'ora. Ci sono alcuni articoli qui su SO, ma sembrano coprire solo l'aggiunta di attributi aggiuntivi al progettista di proprietà.

+1

Questa è la vostra bibbia: http://msdn.microsoft.com/en-us/library/c5z9s1h4.aspx –

+1

@DavidePiras grazie per me questo puntamento! Immagino che ci vorranno alcuni sforzi per completare ma questo sembra essere un buon punto di partenza ... – mfeineis

+0

Ho trovato una soluzione vedere la modifica ... – mfeineis

risposta

3

Edith dice: Su richiesta, una risposta alla mia domanda ...

Questa è la soluzione che è adatto per la mia applicazione. È fondamentalmente un esempio di msdn con alcuni colpi di scena per convincere il designer personalizzato a utilizzare una richiamata al clic. Spero che aiuti chiunque :-).

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] 
public class TabButtonDesigner : System.Windows.Forms.Design.ControlDesigner 
{ 
    ShowTabGlyph myGlyph = null; 
    Adorner myAdorner; 

    public TabButtonDesigner() 
    { 
    } 

    public override void Initialize(IComponent component) 
    { 
     base.Initialize(component); 

     // Add the custom set of glyphs using the BehaviorService. 
     // Glyphs live on adornders. 
     myAdorner = new Adorner(); 
     BehaviorService.Adorners.Add(myAdorner); 
     myGlyph = new ShowTabGlyph(BehaviorService, Control); 
     myGlyph.Callback =() => 
     { 
      ((MyCustomTabButton)this.Control).ShowMyTab(); 
     }; 
     myAdorner.Glyphs.Add(myGlyph); 
    } 

    class ShowTabGlyph : Glyph 
    { 
     Control control; 
     BehaviorService behaviorSvc; 

     public Action Callback 
     { 
      get; 
      set; 
     } 

     public ShowTabGlyph(BehaviorService behaviorSvc, Control control) : 
      base(new ShowTabBehavior()) 
     { 
      this.behaviorSvc = behaviorSvc; 
      this.control = control; 
     } 

     public override Rectangle Bounds 
     { 
      get 
      { 
       // Create a glyph that is 10x10 and sitting 
       // in the middle of the control. Glyph coordinates 
       // are in adorner window coordinates, so we must map 
       // using the behavior service. 
       Point edge = behaviorSvc.ControlToAdornerWindow(control); 
       Size size = control.Size; 
       Point center = new Point(edge.X + (size.Width/2), 
        edge.Y + (size.Height/2)); 

       Rectangle bounds = new Rectangle(
        center.X - 5, 
        center.Y - 5, 
        10, 
        10); 

       return bounds; 
      } 
     } 

     public override Cursor GetHitTest(Point p) 
     { 
      // GetHitTest is called to see if the point is 
      // within this glyph. This gives us a chance to decide 
      // what cursor to show. Returning null from here means 
      // the mouse pointer is not currently inside of the glyph. 
      // Returning a valid cursor here indicates the pointer is 
      // inside the glyph, and also enables our Behavior property 
      // as the active behavior. 
      if (Bounds.Contains(p)) 
      { 
       return Cursors.Hand; 
      } 

      return null; 
     } 

     public override void Paint(PaintEventArgs pe) 
     { 
      // Draw our glyph. It is simply a blue ellipse. 
      pe.Graphics.DrawEllipse(Pens.Blue, Bounds); 
     } 

     // By providing our own behavior we can do something interesting 
     // when the user clicks or manipulates our glyph. 
     class ShowTabBehavior : Behavior 
     { 
      public override bool OnMouseUp(Glyph g, MouseButtons button) 
      { 
       //MessageBox.Show("Hey, you clicked the mouse here"); 
       //this. 
       ShowTabGlyph myG = (ShowTabGlyph)g; 
       if (myG.Callback != null) 
       { 
        myG.Callback(); 
       } 
       return true; // indicating we processed this event. 
      } 
     } 
    } 
} 

[DesignerAttribute(typeof(TabButtonDesigner))] 
public class MyCustomTabButton : System.Windows.Forms.Button 
{ 
    // The attribute will assign the custom designer to the TabButton 
    // and after a rebuild the button contains a centered blue circle 
    // that acts at design time like the button in runtime does ... 

    // ... 
} 
+0

questo non ha funzionato per me. VisualStyleElement.TreeView.Glyph è sigillato e non posso eseguire l'override, inoltre voglio rendere un pulsante selezionabile, non un pulsante – deadManN

Problemi correlati