1

我正在制作一个自定义井字游戏,其中表格中有三个井字游戏帧。

与其创建三次 3x3 正方形按钮,我认为创建一个自定义控件会更好,该控件将包含我想要的九个按钮,因此我可以在表单中放置三次,并访问每一个按钮。

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

4

4 回答 4

4

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


更新

这里有更多的解释。将 aTableLayoutPanel放在UserControl. 更改DockFill。添加一行和一列以便同时拥有三个并将它们的大小模式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));
        }
    }
}

为属性窗口中所有按钮的单击事件选择事件处理程序“button_Click”,切换为事件(闪烁符号)。不要为每个按钮创建一个新按钮。按 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);

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

于 2012-12-06T16:16:26.077 回答
2

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

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);
            }
        }
    }
于 2012-12-06T16:39:03.007 回答
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();  
        }  

    }  
}  
于 2016-02-20T13:02:21.433 回答
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;
...
于 2012-12-06T16:19:44.490 回答