在 C# 中单击圆对象时如何移动它

How do you move a circle object when it is clicked on in C#

我正在尝试用 C# 制作跳棋。单击一块时我无法移动它。现在我只想让它移动到任何地方。它正在做的是在它需要移动时创建一个新的 piece 对象实例。任何帮助都会非常感谢。这是代码。

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();
    }
}

没有 a good, minimal, complete code example 就不可能确定最好的建议是什么。但是考虑到你的问题陈述:

What it is doing is creating a new instance of the piece object when it needs to just move

…至少可以确定导致该错误的具体错误并提供一些建议。

您获得 pieceObject class 的新实例的原因是您在每次引发表单的 Paint 事件时创建它们。重要的是要了解 Paint 事件在每次 Windows 决定 window 需要重绘时引发 。这不是一次性的事情。

根据您目前在设计方面的方向,您似乎真的只希望您放入 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);
        }
    }
}

然后,不要在每次引发表单的 Paint 事件时都创建 pieceObject 实例,只需在创建表单时创建一次:

    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);
    }

备注:

  • 在上面我还删除了几个地方你创建了一个白色的画笔,没有使用它,然后没有处理它。
  • 您在 pieceObject 上使用 Click 事件在几个方面是错误的:首先,lambda 表达式捕获了 Paint 事件的发送者和事件参数,不是随事件实际发送的 ab;其次,首先不需要将事件处理程序包装在 lambda 中,因为您可以将 Click 事件的实际 sender 转换为实际上的 pieceObject发送事件。