在Visual Studio中设计时在设计时单击按钮?

mfe*_*eis 7 c# design-time custom-controls visual-studio winforms

我的设置: 我在Visual Studio 2008中有一个C#应用程序(.NET 3.5).没有机会切换到WPF或者无论如何:).

我的应用程序包含一个自定义控件(从Windows.Forms.Button派生的按钮类),它可以替代Windows.Forms.TabControl.我可以将这些按钮相互关联,每个按钮可以与它正在处理的一个控件相关联(通常是某种类型的Windows.Forms.Panel).它看起来像这样:

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

基本上它只是单击一个按钮,显示其绑定控件并使绑定到相关按钮的控件消失 - 就像TabControl一样,但该方法很容易设计,我可以将按钮放在远离其内容面板的位置.

问题: 这在运行时非常有效,但在设计时的使用可以说是奇怪的:使用鼠标,找到属于该组的控件并运行一系列<Send To Back>s直到所需的控件可见.

问题: 有没有办法告诉VS设计师在设计时评估按钮的点击次数,就像使用TabControl一样,这样我就可以像在运行时一样点击它们来切换标签?

我一直在寻找相当长的一段时间.这里有一些文章,但它们似乎只是为了向属性设计师添加其他属性.

mfe*_*eis 4

伊迪丝说: 根据要求,回答我自己的问题......

这是适合我的应用程序的解决方案。它基本上是 msdn 中的一个示例,经过一些修改,让自定义设计器在单击时使用回调。希望它对任何人都有帮助:-)。

[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 ...

    // ...
}
Run Code Online (Sandbox Code Playgroud)