创建自定义按钮控件

时间:2012-12-06 16:10:08

标签: c# winforms custom-controls

我正在制作一个定制的Tic Tac Toe游戏,表格中有三个Tic Tac Toe框架。

而不是创建三倍于3x3方形的按钮,我认为最好制作一个自定义控件,其中包含我想要的阵型中的九个按钮,因此我可以在表单中放置三次并访问该阵型中的每一个按钮。

我对继承和自定义控件很陌生,所以我希望得到您的示例或说明帮助。

4 个答案:

答案 0 :(得分:3)

在这种情况下,您可以使用UserControl。这比创建自定义控件更容易,自定义控件需要从现有控件派生控件并对其进行增强。在VS中右键单击您的项目并选择“添加”> “新物品...”。在Windows窗体部分中,选择“用户控件”。将其命名为“TicTacToeUserControl”。您可以像设计表单一样设计用户控件。然后,它将自动显示在当前项目的工具箱中,并准备好放在表单上。


<强>更新

这里有更多解释。在TableLayoutPanel上放置UserControl。将Dock更改为Fill。添加行和列以使两者中的三个都更改并将其大小模式更改为Percent并将这些值更改为33.33。从左到右,然后从上到下为每个表字段添加一个按钮,以便按阅读顺序将按钮命名为“button1”,“button2”等。保存用户控件(我的VS在这一点上有一个小故障,我不得不重新开始)。

创建我们将用作按钮点击事件的事件参数的类

public class ButtonClickedEventArgs : EventArgs
{
    public ButtonClickedEventArgs(TicTacToeUserControl userControl, Button button,
                                  int buttonNumber, int row, int column)
    {
        UserControl = userControl;
        Button = button;
        ButtonNumber = buttonNumber;
        Row = row;
        Column = column;
    }

    public TicTacToeUserControl UserControl { get; private set; }
    public Button Button { get; private set; }
    public int ButtonNumber { get; private set; }
    public int Row { get; private set; }
    public int Column { get; private set; }
}

更改用户控件的代码,使其看起来像这样

[DefaultEvent("ButtonClicked")]
public partial class TicTacToeUserControl : UserControl
{
    public event EventHandler<ButtonClickedEventArgs> ButtonClicked;

    public TicTacToeUserControl()
    {
        InitializeComponent();
    }

    private void button_Click(object sender, EventArgs e)
    {
        OnButtonClicked((Button)sender);
    }

    private void OnButtonClicked(Button button)
    {
        var eh = ButtonClicked;
        if (eh != null) {
            int buttonNumber =
                Int32.Parse(button.Name.Substring(button.Name.Length - 1));
            int row = (buttonNumber - 1) / 3;
            int col = (buttonNumber - 1) % 3;
            eh(this, 
               new ButtonClickedEventArgs(this, button, buttonNumber, row, col));
        }
    }
}

为属性窗口中所有按钮的click事件选择事件处理程序“button_Click”切换到Event(闪存符号)。不要为每个按钮创建一个新的按钮。点击F6(编译)

您的控件已准备就绪,可以从工具窗口拖放到表单上。根据需要调整大小。双击它。由于我们为表单指定了DefaultEventAttribute,VS将自动创建此事件处理程序

private void ticTacToeUserControl1_ButtonClicked(object sender,
                                                 ButtonClickedEventArgs e)
{
}

将此代码行添加到其中以测试用户控件

    MessageBox.Show(e.UserControl.Name + " " + e.Button.Name + " " + 
                    e.ButtonNumber + " " + e.Row + " " + e.Column);

注意:这实际上并没有创建新控件,只是创建了一个模板

答案 1 :(得分:1)

最好的方法是使用用户控件,但不是通过设计器创建按钮,而是通过代码创建按钮,这将帮助您检测单击的按钮;

public partial class UserControl1 : UserControl
    {
        private List<Button> buttons = new List<Button>(9);
        public UserControl1()
        {
            InitializeComponent();
        }

        private void UserControl1_Load(object sender, EventArgs e)
        {
            int line = 0;
            int lastleft = 0;
            int lasttop = 0;
            for (int i = 1; i < 10; i++)
            {
                Button btn = new Button();
                btn.Text = string.Empty;
                btn.Parent = this;
                btn.Top = lasttop;
                btn.Left = lastleft;
                btn.Width = 30;
                btn.Height = 30;
                btn.Name = i.ToString(CultureInfo.InvariantCulture);

                if (i % 3 == 0)
                {
                    lastleft = 0;
                    lasttop += 35; // 30 for height and 5 for spacing
                }
                else
                {
                    lastleft += 35; // 30 for width and 5 for spacing
                }
                btn.Click += BtnOnClick;
                buttons.Add(btn);

            }
        }

        private void BtnOnClick(object sender, EventArgs eventArgs)
        {
            //ur logic to check game status
            // how to know button?
            Button btn = sender as Button;

            if (btn != null)
            {
                MessageBox.Show(String.Format("You clicked : {0}", btn.Name), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }

答案 2 :(得分:1)

using System;  
using System.Collections.Generic;  
using System.Text;  
using System.Drawing;  
using System.Data;  
using System.Windows.Forms;  
namespace ButtonZ  
{  
    public class ButtonZ : System.Windows.Forms.Button  
    {  
        Color clr1, clr2;  
        private Color color1 = Color.LightGreen;  
        private Color color2 = Color.DarkBlue;  
        private Color m_hovercolor1 = Color.Yellow;  
        private Color m_hovercolor2 = Color.DarkOrange;  
        private int color1Transparent = 150;  
        private int color2Transparent = 150;  
        private Color clickcolor1 = Color.DarkOrange;  
        private Color clickcolor2 = Color.Red;  
        private int angle = 90;  
        private int textX = 100;  
        private int textY = 25;  
        private String text = "";  

        //Create Properties to read Button Text,Colors etc  
        public String DisplayText  
        {  
            get { return text; }  
            set { text = value; Invalidate(); }  
        }  

        public Color StartColor  
        {  
            get { return color1; }  
            set { color1 = value; Invalidate(); }  
        }  

        public Color EndColor  
        {  
            get { return color2; }  
            set { color2 = value; Invalidate(); }  
        }  

        public Color MouseHoverColor1  
        {  
            get { return m_hovercolor1; }  
            set { m_hovercolor1 = value; Invalidate(); }  
        }  

        public Color MouseHoverColor2  
        {  
            get { return m_hovercolor2; }  
            set { m_hovercolor2 = value; Invalidate(); }  
        }  

        public Color MouseClickColor1  
        {  
            get { return clickcolor1; }  
            set { clickcolor1 = value; Invalidate(); }  
        }  

        public Color MouseClickColor2  
        {  
            get { return clickcolor2; }  
            set { clickcolor2 = value; Invalidate(); }  
        }  

        public int Transparent1  
        {  
            get { return color1Transparent; }  
            set  
            {  
                color1Transparent = value;  
                if (color1Transparent > 255)  
                {  
                    color1Transparent = 255;  
                    Invalidate();  
                }  
                else  
                    Invalidate();  
            }  
        }  

        public int Transparent2  
        {  
            get { return color2Transparent; }  
            set  
            {  
                color2Transparent = value;  
                if (color2Transparent > 255)  
                {  
                    color2Transparent = 255;  
                    Invalidate();  
                }  
                else  
                    Invalidate();  
            }  
        }  

        public int GradientAngle  
        {  
            get { return angle; }  
            set { angle = value; Invalidate(); }  
        }  

        public int TextLocation_X  
        {  
            get { return textX; }  
            set { textX = value; Invalidate(); }  
        }  

        public int TextLocation_Y  
        {  
            get { return textY; }  
            set { textY = value; Invalidate(); }  
        }  

        public ButtonZ()  
        {  
            this.Size = new System.Drawing.Size(200, 50);  
            this.ForeColor = Color.White;  
            this.FlatStyle = System.Windows.Forms.FlatStyle.Flat;  
            text = this.Text;  
        }  

        //method mouse enter  
        protected override void OnMouseEnter(EventArgs e)  
        {  
            base.OnMouseEnter(e);  
            clr1 = color1;  
            clr2 = color2;  
            color1 = m_hovercolor1;  
            color2 = m_hovercolor2;  
        }  

        //method mouse leave  
        protected override void OnMouseLeave(EventArgs e)  
        {  
            base.OnMouseLeave(e);  
            color1 = clr1;  
            color2 = clr2;  
        }  

        //method mouse click  
        protected override void OnMouseClick(MouseEventArgs e)  
        {  
            if (e.Clicks == 1)  
            {  
                base.OnMouseClick(e);  
                color1 = clickcolor1;  
                color2 = clickcolor2;  
            }  
        }  

        protected override void OnPaint(PaintEventArgs pe)  
        {  
            base.OnPaint(pe);  
            text = this.Text;  
            if (textX == 100 && textY == 25)  
            {  
                textX = ((this.Width) / 3) + 10;  
                textY = (this.Height / 2) - 1;  
            }  
            Color c1 = Color.FromArgb(color1Transparent, color1);  
            Color c2 = Color.FromArgb(color2Transparent, color2);  
            //drawing string & filling gradient rectangle   
            Brush b = new System.Drawing.Drawing2D.LinearGradientBrush(ClientRectangle, c1, c2, angle);  
            Point p = new Point(textX, textY);  
            SolidBrush frcolor = new SolidBrush(this.ForeColor);  
            Border3DStyle borderStyle = Border3DStyle.SunkenInner;  
            pe.Graphics.FillRectangle(b, ClientRectangle);  
            pe.Graphics.DrawString(text, this.Font, frcolor, p);  
            ControlPaint.DrawBorder3D(pe.Graphics, ClientRectangle, borderStyle);  
            b.Dispose();  
        }  

    }  
}  

答案 3 :(得分:0)

这不是一个答案,但它的评论太长了(所以请不要拒绝投票而不是答案)


在这种情况下,我不会使用自定义控件,而只是使用控件数组。

例如,只需在网格形式中制作9个控件,然后将它们分配给数组

Button[][] buttons = new Button[ROW_COUNT][];
for (int i = 0; i < ROW_COUNT; i++)
{
    buttons[i] = new Buttons[COLUMN_COUNT];
}
buttons[0][0] = btnTopLeft;
...