首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将值从类传递到不同的窗体上显示&以编程方式单击事件处理?

将值从类传递到不同的窗体上显示&以编程方式单击事件处理?
EN

Stack Overflow用户
提问于 2011-10-19 17:20:04
回答 4查看 364关注 0票数 1

我目前已经创建了一个棋盘,填充了棋子的图像,并对棋盘进行了着色等,我有2个点击事件方法的问题,我希望你能帮助我?当一个正方形被点击时,我当前的方法改变了正方形的颜色,并显示一个消息框,显示xy坐标和棋子的类型,或者如果它没有被棋子占据,就显示坐标:

问题1:如果我再次单击相同的方块或不同的方块,如何让颜色变回原来的颜色?

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

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

代码语言:javascript
复制
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 + ")");
                }
        }
    }
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-10-19 18:05:04

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

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

首先,重新编码GridSquare,如下所示:

代码语言:javascript
复制
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集合中。如果是这样的话,你需要像这样写代码:

代码语言:javascript
复制
for (var x = 0; x < 8; x++)
{
    for (var y = 0; y < 8; y++)
    {
        this.Controls.Add(new GridSquare(x, y, clicked));
    }
}

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

代码语言:javascript
复制
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);
    }
};

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

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

如果这对你有效,请告诉我。

票数 2
EN

Stack Overflow用户

发布于 2011-10-19 17:28:55

首先将长方体的实际颜色存储在一个color类的对象中,让我们假设对象名为"BoxColor“,现在请看以下代码。

代码语言:javascript
复制
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 + ")";     
} 

还要设置一个布尔变量,只有当框的颜色从实际颜色改变时才启用它,现在如果用户单击任何其他框,检查这些标志,并检查它是否为真,重置颜色。

票数 1
EN

Stack Overflow用户

发布于 2011-10-19 17:31:49

  1. 您可以在GridSquare类的作用域上创建一个boolean变量。然后在gridSquare_Click事件处理程序上使用此变量,如下所示:

公共类GridSquare : PictureBox { bool isFirstClick = true;.......private void gridSquare_Click(object sender,EventArgs e) { if( isFirstClick ) { isFirstClick = false;//设置一种颜色} else {isFirstClick= true;//设置其他颜色}

  • 只需使用TextLabel的属性即可
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7819084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档