我正试图用C#制作中国跳棋。点击它时,我无法移动它。现在我只想让它移动到哪里。它正在做的是在需要移动时创建一个新的工件对象实例。任何帮助都会非常感谢你。这是代码。
namespace ChineseCheckers
{
public partial class mainForm : Form
{
private Board thisBoard = new Board();
public event PaintEventHandler paint;
public mainForm()
{
InitializeComponent();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void mainForm_Paint(object sender, PaintEventArgs e)
{
int width = 15;
int del = 3;
int ystart = 50;
int xstart = ystart+4 * width;
SolidBrush whiteSB = new SolidBrush(Color.White);
for (int i = 0; i < 17; i++)
{
for (int j = 0; j < 17; j++)
{
if (Board.isSpace(i, j))
{
Space sp = thisBoard.getSpace(i, j);
int xPos = getXFromIndex(i, j, width, xstart, ystart);
int yPos = getYFromIndex(i, j, width, xstart, ystart);
pieceObject piece = new pieceObject(e, xPos - del, yPos - del, getColor(sp));
EventHandler myhandler = new EventHandler((a, b)=>myButton_Click(sender, e, piece));
piece.Click += myhandler;
piece.Size = new System.Drawing.Size(20, 20);
piece.Location = new System.Drawing.Point(xPos - del, yPos - del);
piece.BackColor = getColor(sp);
this.Controls.Add(piece);
}
}
}
}
private int getYFromIndex(int i, int j, int width, int xstart, int ystart)
{
return ystart + (2 * i) * width;
}
private int getIFromXY(int x, int y, int width, int xstart, int ystart)
{
return (y - ystart + width) / (2 * width);
}
private int getXFromIndex(int i, int j, int width, int xstart, int ystart)
{
return xstart + (2 * j - i) * width;
}
private int getJFromXY(int x, int y, int width, int xstart, int ystart)
{
int i = getIFromXY(x, y, width, xstart, ystart);
return (((x - xstart+ width/2) / width) + i) / 2;
}
private Color getColor(Space sp)
{
switch (sp)
{
case Space.Player1:
return Color.Orange;
case Space.Player2:
return Color.Yellow;
case Space.Player3:
return Color.Green;
case Space.Player4:
return Color.Blue;
case Space.Player5:
return Color.Purple;
case Space.Player6:
return Color.Red;
}
return Color.Gray;
}
private void newGameToolStripMenuItem_Click(object sender, EventArgs e)
{
Form currentForm = mainForm.ActiveForm;
currentForm.BackgroundImage = null;
currentForm.BackColor = Color.Black;
currentForm.Width = 600;
currentForm.Height = 650;
Button endTurn = new Button();
endTurn.Location = new Point(485, 575);
endTurn.Text = "End Turn";
endTurn.BackColor = Color.Wheat;
endTurn.Click += new EventHandler(endTurnEvent);
this.Controls.Add(endTurn);
}
public void endTurnEvent(object sender, EventArgs e)
{
System.Console.WriteLine("You have ended your turn!");
}
private void mainForm_MouseClick(object sender, MouseEventArgs e)
{
}
void myButton_Click(Object sender, System.EventArgs e, pieceObject piece)
{
System.Console.WriteLine("Position: " + piece.Location + "Color: " + piece.BackColor);
piece.Location = new Point(40, 40);
}
}
}
public class pieceObject : UserControl
{
// Draw the new button.
public pieceObject(PaintEventArgs e, int xPos, int yPos, Color color)
{
int width = 15;
SolidBrush whiteSB = new SolidBrush(color);
SolidBrush newPiece = new SolidBrush(color);
e.Graphics.FillEllipse(newPiece, xPos, yPos, width, width);
newPiece.Dispose();
}
}
答案 0 :(得分:1)
如果没有a good, minimal, complete code example,就无法确定最佳建议是什么。但鉴于你的问题陈述:
它正在做的是在需要移动
时创建一个新的工件对象实例
...至少可以确定导致该问题的具体错误并提供一些建议。
您获取pieceObject
课程的新实例的原因是,每次提出表单的Paint
事件时,您都会创建它们。重要的是要了解每次都会引发Paint
事件 Windows决定需要重新绘制窗口。它不仅仅是一次性的事情。
根据您当前在设计方面看起来的方向,您似乎真的只希望您在Paint
事件处理程序中放置的代码只执行一次。如果是这样,我建议您按如下方式更改代码:
首先,修复pieceObject
,以便根据需要自行绘制:
public class pieceObject : UserControl
{
private readonly Color _color;
public pieceObject(Color color) { _color = color; }
// Draw the new button.
protected override void OnPaint(PaintEventArgs e)
{
int width = 15;
using (SolidBrush newPiece = new SolidBrush(_color))
{
e.Graphics.FillEllipse(newPiece, 3, 3, width, width);
}
}
}
然后,每次提出表单的pieceObject
事件时,不要创建Paint
个实例,只需在创建表单时执行一次:
public mainForm()
{
InitializeComponent();
InitializePieceControls();
}
private void InitializePieceControls()
{
int width = 15;
int del = 3;
int ystart = 50;
int xstart = ystart+4 * width;
for (int i = 0; i < 17; i++)
{
for (int j = 0; j < 17; j++)
{
if (Board.isSpace(i, j))
{
Space sp = thisBoard.getSpace(i, j);
int xPos = getXFromIndex(i, j, width, xstart, ystart);
int yPos = getYFromIndex(i, j, width, xstart, ystart);
pieceObject piece = new pieceObject(getColor(sp));
piece.Click += myButton_Click;
piece.Size = new System.Drawing.Size(20, 20);
piece.Location = new System.Drawing.Point(xPos - del, yPos - del);
// It's not clear why you are doing this, as it will just make
// it impossible to see the ellipse that is drawn by the piece
// itself
piece.BackColor = getColor(sp);
this.Controls.Add(piece);
}
}
}
}
void myButton_Click(object sender, EventArgs e)
{
pieceObject piece = (pieceObject)sender;
System.Console.WriteLine("Position: " + piece.Location + "Color: " + piece.BackColor);
piece.Location = new Point(40, 40);
}
备注:强>
Click
上对pieceObject
事件的使用在以下几个方面是错误的:首先,lambda表达式捕获了Paint
事件的发送方和事件参数,而不是a
和b
实际发送了此事件;第二,首先不需要在lambda中包装事件处理程序,因为你可以将sender
事件的实际Click
转换为事实上的pieceObject
发送活动。