从类传递值以不同的形式显示以编程方式处理单击事件?

发布于 2024-12-10 11:23:22 字数 2408 浏览 0 评论 0原文

我目前创建了一个国际象棋棋盘,其中填充了棋子的图像,并对棋盘进行了着色等,我在点击事件方法方面有两个问题,希望您能帮助我解决?当单击一个方块时,我当前的方法会更改方块颜色并显示一个消息框,其中显示 xy 坐标和块类型,或者如果它没有被块占据,则仅显示坐标:

问题 1:如何更改颜色如果我再次单击同一个正方形或不同的正方形,回到原来的状态?

问题 2:如何在文本框或标签中显示 Form1.cs 上的信息,而不是显示消息框?

以下是我的 GridSqaure.cs 类中的代码:

namespace Chess
{
    public class GridSquare : PictureBox
    {
        private int x;
        private int y;

        private ChessPiece piece;

        public int X { get { return x; } }
        public int Y { get { return y; } }

        public ChessPiece Piece 
        {
            get { return piece; }
            set 
            {
                piece = value;
                if (value == null)
                    this.BackgroundImage = null;
                else
                    this.BackgroundImage = piece.GetImage();
            }
        }

        public GridSquare(int x, int y)
        {
            int ButtonWidth = 64;
            int ButtonHeight = 64;
            int Distance = 20;
            int start_x = 10;
            int start_y = 10;

            this.x = x;
            this.y = y;

            this.Top = start_x + (x * ButtonHeight + Distance + x);
            this.Left = start_y + (y * ButtonWidth + Distance + y);
            this.Width = ButtonWidth;
            this.Height = ButtonHeight;
            this.Text = "X: " + x.ToString() + " Y: " + y.ToString();

            this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;

            this.Click += new System.EventHandler(gridSquare_Click);
        }

        private void gridSquare_Click(object sender, EventArgs e)
        {
            GridSquare gs = (GridSquare)sender;
            if (gs.Piece != null)
                {
                    //Change: need to show xy of sqaure clicked on a label or textbox on the main window.
                MessageBox.Show("You clicked a " + gs.Piece.GetName() + " at (" + gs.X + ", " + gs.Y + ")");

                //Change: need to click for change in colour, then second click to revert back
                this.BackColor = Color.LightBlue;
                } 
            else
                {
                    //Change: need to show xy of clicked square but including meesage stating the sqaure needs to be occupied by a piece.
                    MessageBox.Show("You clicked (" + gs.X + ", " + gs.Y + ")");
                }
        }
    }
}

ive currently created a chess board populated with images of the pieces in place and have coloured the board etc, i have 2 issues with the click event method of which im hoping you could help me on? when a square is clicked my current method changes the sqaure colour and displays a messagebox showing the xy co-ordinates and type of piece or just co-ordinates if its not occupied by a piece :

Issue 1 : How can i get the colour to change back to its original if i click the same sqaure again or a different sqaure?

Issue 2 : How would i instead of showing a meesagebox, display the information on Form1.cs in a textbox or label?

The following is my code from my GridSqaure.cs class:

namespace Chess
{
    public class GridSquare : PictureBox
    {
        private int x;
        private int y;

        private ChessPiece piece;

        public int X { get { return x; } }
        public int Y { get { return y; } }

        public ChessPiece Piece 
        {
            get { return piece; }
            set 
            {
                piece = value;
                if (value == null)
                    this.BackgroundImage = null;
                else
                    this.BackgroundImage = piece.GetImage();
            }
        }

        public GridSquare(int x, int y)
        {
            int ButtonWidth = 64;
            int ButtonHeight = 64;
            int Distance = 20;
            int start_x = 10;
            int start_y = 10;

            this.x = x;
            this.y = y;

            this.Top = start_x + (x * ButtonHeight + Distance + x);
            this.Left = start_y + (y * ButtonWidth + Distance + y);
            this.Width = ButtonWidth;
            this.Height = ButtonHeight;
            this.Text = "X: " + x.ToString() + " Y: " + y.ToString();

            this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;

            this.Click += new System.EventHandler(gridSquare_Click);
        }

        private void gridSquare_Click(object sender, EventArgs e)
        {
            GridSquare gs = (GridSquare)sender;
            if (gs.Piece != null)
                {
                    //Change: need to show xy of sqaure clicked on a label or textbox on the main window.
                MessageBox.Show("You clicked a " + gs.Piece.GetName() + " at (" + gs.X + ", " + gs.Y + ")");

                //Change: need to click for change in colour, then second click to revert back
                this.BackColor = Color.LightBlue;
                } 
            else
                {
                    //Change: need to show xy of clicked square but including meesage stating the sqaure needs to be occupied by a piece.
                    MessageBox.Show("You clicked (" + gs.X + ", " + gs.Y + ")");
                }
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

滴情不沾 2024-12-17 11:23:22

我会避免让一个类处理它自己的事件之一。这不是一个好的做法。

相反,我会使用回调策略。

首先,像这样重新编码 GridSquare:

public class GridSquare : PictureBox
{
    /* As before */

    public GridSquare(int x, int y, Action<GridSquare> clicked)
    {
        /* As before */
        this.Click += (s, e) => clicked(this);
    }

    /* NO private void gridSquare_Click(object sender, EventArgs e) */
}

现在由调用代码来完成艰苦的工作。

我假设您正在使用类似嵌套 for 循环之类的东西来创建板,该循环将每个创建的 GridSquare 添加到表单的 Controls 集合中。如果是这种情况,您需要像这样编写代码:

for (var x = 0; x < 8; x++)
{
    for (var y = 0; y < 8; y++)
    {
        this.Controls.Add(new GridSquare(x, y, clicked));
    }
}

现在您只需要定义 clicked - 单击每个 GridSquare 时的回调 - 该代码如下所示:

GridSquare lastClicked = null;
Color lastBackColor = Color.Transparent;

Action<GridSquare> clicked = gs =>
{
    lastClicked.BackColor = lastBackColor;
    if (!lastClicked.Equals(gs))
    {
        lastClicked = gs;
        lastBackColor = gs.BackColor;
        gs.BackColor = Color.LightBlue;
        var inner = gs.Piece != null
            ? String.Format("a {0} at ", gs.Piece.GetName())
            : "";
        var msg = String.Format("You clicked {0}({1}, {2})", inner, gs.X, gs.Y);
        MessageBox.Show(msg);
    }
};

显然,这段代码是在创建网格方块之前执行的。

这应该相对容易理解,但如果不是,请询问,我会详细说明。

让我知道这是否适合您。

I would avoid having a class handle one of its own events. It isn't a good practice.

Instead, I would use a callback strategy.

First, recode GridSquare like this:

public class GridSquare : PictureBox
{
    /* As before */

    public GridSquare(int x, int y, Action<GridSquare> clicked)
    {
        /* As before */
        this.Click += (s, e) => clicked(this);
    }

    /* NO private void gridSquare_Click(object sender, EventArgs e) */
}

Now it is up to the calling code to do the hard work.

I assume that you're creating the board using something like nested for loops that add each created GridSquare to the form's Controls collection. If that's the case you would need to write your code like this:

for (var x = 0; x < 8; x++)
{
    for (var y = 0; y < 8; y++)
    {
        this.Controls.Add(new GridSquare(x, y, clicked));
    }
}

Now you just need to define clicked - the callback when each GridSquare is clicked - and that code looks like this:

GridSquare lastClicked = null;
Color lastBackColor = Color.Transparent;

Action<GridSquare> clicked = gs =>
{
    lastClicked.BackColor = lastBackColor;
    if (!lastClicked.Equals(gs))
    {
        lastClicked = gs;
        lastBackColor = gs.BackColor;
        gs.BackColor = Color.LightBlue;
        var inner = gs.Piece != null
            ? String.Format("a {0} at ", gs.Piece.GetName())
            : "";
        var msg = String.Format("You clicked {0}({1}, {2})", inner, gs.X, gs.Y);
        MessageBox.Show(msg);
    }
};

Obviously this code goes before the creation of the grid squares.

This should be relatively easy to follow, but if not, just ask and I'll elaborate.

Let me know if this works for you.

永不分离 2024-12-17 11:23:22

首先将盒子的实际颜色存储在 Color 类的对象中,假设对象名称为“BoxColor”,现在看下面的代码。

if (gs.Piece != null) 
{      
    //Change: need to show xy of sqaure clicked on a label or textbox on the main window.       
    label1.Text = "You clicked a " + gs.Piece.GetName() + " at (" + gs.X + ", " + gs.Y + ")";       
   //Change: need to click for change in colour, then second click to revert back           
  this.BackColor = Color.LightBlue;  
}        
else         
{             
    //Change: need to show xy of clicked square but including meesage stating the sqaure needs to be occupied by a piece.   
     this.BackColor = BoxColor //setting back the original color if the box is clicked again.
     label1.Text = "You clicked (" + gs.X + ", " + gs.Y + ")";     
} 

并且还放置一个布尔变量,仅当框的颜色从其实际颜色更改时才启用它,现在如果用户单击任何其他框,请检查这些标志,如果其为 true,则重置颜色。

First store the actual color of the box in an object of Color class, lets assume the object name is "BoxColor" and now see the following code.

if (gs.Piece != null) 
{      
    //Change: need to show xy of sqaure clicked on a label or textbox on the main window.       
    label1.Text = "You clicked a " + gs.Piece.GetName() + " at (" + gs.X + ", " + gs.Y + ")";       
   //Change: need to click for change in colour, then second click to revert back           
  this.BackColor = Color.LightBlue;  
}        
else         
{             
    //Change: need to show xy of clicked square but including meesage stating the sqaure needs to be occupied by a piece.   
     this.BackColor = BoxColor //setting back the original color if the box is clicked again.
     label1.Text = "You clicked (" + gs.X + ", " + gs.Y + ")";     
} 

And also put one boolean variable enable it only when the color of the box is changed from its actual color and now if the user clicks on any other boxes check for these flag and if its true reset the color.

苏大泽ㄣ 2024-12-17 11:23:22
  1. 您可以在类 GridSquare 的范围内创建一个 boolean 变量。然后在 gridSquare_Click 事件处理程序上使用此变量,如下所示:

    公共类 GridSquare : PictureBox
    {
       布尔 isFirstClick = true;
       ……
       ……
       ……
       私人无效gridSquare_Click(对象发送者,EventArgs e)
        {
               if(是第一次点击)
               {
                   isFirstClick = false; 
                   //设置一种颜色
                }
               别的
               {
                   isFirstClick = true;
                   //设置其他颜色
               } 
         } 
    }
    
  2. 只需使用 LabelTextBoxText 属性.

  1. You can create a boolean variable on the scope of your class GridSquare. Then use this variable on gridSquare_Click event handler like this:

    public class GridSquare : PictureBox
    {
       bool isFirstClick = true;
       .....
       .....
       .....
       private void gridSquare_Click(object sender, EventArgs e)
        {
               if(isFirstClick)
               {
                   isFirstClick = false; 
                   //Set one color
                }
               else
               {
                   isFirstClick = true;
                   //Set other color
               } 
         } 
    }
    
  2. Simply use Text property of Label or TextBox.

最舍不得你 2024-12-17 11:23:22

这就是我将原始代码修改为:

namespace Chess
{
public class GridSquare : PictureBox
{
    private int x;
    private int y;

    private static GridSquare lastClicked;
    private static ChessBoard board;

    private ChessPiece piece;

    public int X { get { return x; } }
    public int Y { get { return y; } }
    public static ChessBoard Board { set { board = value; } }

    Color LightTile = Color.Beige;
    Color DarkTile = Color.SandyBrown;

    public ChessPiece Piece 
    {
        get { return piece; }
        set 
        {
            piece = value;
            if (value == null)
                this.BackgroundImage = null;
            else
                this.BackgroundImage = piece.GetImage();
        }
    }

    public GridSquare(int x, int y)
    {
        int ButtonWidth = 64;
        int ButtonHeight = 64;
        int Distance = 20;
        int start_x = 10;
        int start_y = 10;

        this.x = x;
        this.y = y;

        this.Top = start_x + (x * ButtonHeight + Distance + x);
        this.Left = start_y + (y * ButtonWidth + Distance + y);
        this.Width = ButtonWidth;
        this.Height = ButtonHeight;
        this.Text = "X: " + x.ToString() + " Y: " + y.ToString();

        this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;

        this.Click += new System.EventHandler(gridSquare_Click);
    }

    private void gridSquare_Click(object sender, EventArgs e)
    {
        GridSquare gs = (GridSquare)sender;

        if (lastClicked != null)
            lastClicked.ResetColour();

        //Change: need to click for change in colour, then second click to revert back
        this.BackColor = Color.LightBlue;
        lastClicked = this;

        if (gs.Piece != null)
        {
            board.StatusLabel.Text = "You clicked a " + gs.Piece.GetName() + " at (" + gs.X + ", " + gs.Y + ")";
        }
        else
        {
            board.StatusLabel.Text = "You clicked (" + gs.X + ", " + gs.Y + ")";
        }
    }

    public void ResetColour()
    {
        if (x % 2 == 0)
            if (y % 2 == 0)
                // If x=Even y=Even
                this.BackColor = LightTile;
            else
                // If x=Even y=Odd
                this.BackColor = DarkTile;
        else
            if (y % 2 == 0)
                // If x=Odd y=Even
                this.BackColor = DarkTile;
            else
                // If x=Odd y=Odd
                this.BackColor = LightTile;
    }
}

}

This is what i ammended my original code to:

namespace Chess
{
public class GridSquare : PictureBox
{
    private int x;
    private int y;

    private static GridSquare lastClicked;
    private static ChessBoard board;

    private ChessPiece piece;

    public int X { get { return x; } }
    public int Y { get { return y; } }
    public static ChessBoard Board { set { board = value; } }

    Color LightTile = Color.Beige;
    Color DarkTile = Color.SandyBrown;

    public ChessPiece Piece 
    {
        get { return piece; }
        set 
        {
            piece = value;
            if (value == null)
                this.BackgroundImage = null;
            else
                this.BackgroundImage = piece.GetImage();
        }
    }

    public GridSquare(int x, int y)
    {
        int ButtonWidth = 64;
        int ButtonHeight = 64;
        int Distance = 20;
        int start_x = 10;
        int start_y = 10;

        this.x = x;
        this.y = y;

        this.Top = start_x + (x * ButtonHeight + Distance + x);
        this.Left = start_y + (y * ButtonWidth + Distance + y);
        this.Width = ButtonWidth;
        this.Height = ButtonHeight;
        this.Text = "X: " + x.ToString() + " Y: " + y.ToString();

        this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;

        this.Click += new System.EventHandler(gridSquare_Click);
    }

    private void gridSquare_Click(object sender, EventArgs e)
    {
        GridSquare gs = (GridSquare)sender;

        if (lastClicked != null)
            lastClicked.ResetColour();

        //Change: need to click for change in colour, then second click to revert back
        this.BackColor = Color.LightBlue;
        lastClicked = this;

        if (gs.Piece != null)
        {
            board.StatusLabel.Text = "You clicked a " + gs.Piece.GetName() + " at (" + gs.X + ", " + gs.Y + ")";
        }
        else
        {
            board.StatusLabel.Text = "You clicked (" + gs.X + ", " + gs.Y + ")";
        }
    }

    public void ResetColour()
    {
        if (x % 2 == 0)
            if (y % 2 == 0)
                // If x=Even y=Even
                this.BackColor = LightTile;
            else
                // If x=Even y=Odd
                this.BackColor = DarkTile;
        else
            if (y % 2 == 0)
                // If x=Odd y=Even
                this.BackColor = DarkTile;
            else
                // If x=Odd y=Odd
                this.BackColor = LightTile;
    }
}

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文