我正在制作一个定制的Tic Tac Toe游戏,表格中有三个Tic Tac Toe框架。
而不是创建三倍于3x3方形的按钮,我认为最好制作一个自定义控件,其中包含我想要的阵型中的九个按钮,因此我可以在表单中放置三次并访问该阵型中的每一个按钮。
我对继承和自定义控件很陌生,所以我希望得到您的示例或说明帮助。
答案 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;
...