2011-12-16 18 views
6

Moje ustawienia: Mam aplikację C# (.NET 3.5) w Visual Studio 2008. Nie ma szansy na przejście na WPF lub cokolwiek :).Umożliwiają kliknięcie przycisku podczas projektowania w Visual Studio?

Moja aplikacja zawiera niestandardową kontrolkę (klasę przycisku wywodzącą się z Windows.Forms.Button), która zastępuje Windows.Forms.TabControl. Mogę skojarzyć te przyciski ze sobą i każdy przycisk może być powiązany z jedną kontrolką, z którą ma do czynienia (zazwyczaj jakiś rodzaj Windows.Forms.Panel). Wygląda to mniej więcej tak:

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

Zasadniczo jest tylko o kliknięcie przycisku, pokazując swoją związanego kontroli i konieczności kontroli związanych z powiązanymi przyciski zniknąć - tak jak w TabControl, ale podejście jest łatwe do zaprojektowania i ja można umieścić przyciski daleko od paneli zawartości.

Problem: Działa to całkiem dobrze w czasie wykonywania, ale użycie w czasie projektowania jest zapewne dziwne: Z myszką, znaleźć that's kontrolne należące do grupy i uruchomić serię <Send To Back> s aż pożądana kontrola jest widoczna.

Pytanie: Czy istnieje jakiś sposób powiadomić projektanta VS ocenić kliknięcia przycisków w czasie projektowania jak to robi z TabControl tak, że mogę przełączyć wypustki po prostu klikając je jak bym na środowisko wykonawcze?

Szukałem już od jakiegoś czasu. W SO istnieje kilka artykułów, ale wydają się one obejmować tylko dodawanie dodatkowych atrybutów do projektanta właściwości.

+1

jest to Twoja Biblia: http://msdn.microsoft.com/en-us/library/c5z9s1h4.aspx –

+1

@DavidePiras dziękuję za wskazanie mi tego! Myślę, że będzie to wymagało pewnych wysiłków, ale to wydaje się być dobrym punktem wyjścia ... – mfeineis

+0

Znalazłem rozwiązanie, zobacz edycję ... – mfeineis

Odpowiedz

3

Edith mówi: zamówienie, odpowiedzi na moje własne pytanie ...

Jest to rozwiązanie, które nadaje się do mojego wniosku. Jest to po prostu przykład z msdn z kilkoma zwrotami akcji, aby projektant użył wywołania zwrotnego po kliknięciu. Mam nadzieję, że to pomoże każdemu :-).

[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

to nie działa dla mnie. VisualStyleElement.TreeView.Glyph jest zapieczętowany i nie mogę go przesłonić, chcę też kliknąć przycisk, a nie tabbutton – deadManN