C# 从类传递值以在不同的窗体上显示&是否以编程方式单击事件处理?

C# 从类传递值以在不同的窗体上显示&是否以编程方式单击事件处理?,c#,winforms,events,class,inheritance,C#,Winforms,Events,Class,Inheritance,我目前创建了一个棋盘,上面有棋子的图像,并给棋盘上色,等等。我有两个关于点击事件方法的问题,我希望你能帮我解决?单击正方形时,我的当前方法会更改sqaure颜色,并显示一个消息框,显示xy坐标和工件类型,如果工件未占用坐标,则仅显示坐标: 问题1:如果我再次单击相同的sqaure或不同的sqaure,如何使颜色恢复到原来的颜色 问题2:如何在文本框或标签中显示Form1.cs上的信息,而不是显示meesagebox 以下是我在GridSqaure.cs类中的代码: namespace Chess

我目前创建了一个棋盘,上面有棋子的图像,并给棋盘上色,等等。我有两个关于点击事件方法的问题,我希望你能帮我解决?单击正方形时,我的当前方法会更改sqaure颜色,并显示一个消息框,显示xy坐标和工件类型,如果工件未占用坐标,则仅显示坐标:

问题1:如果我再次单击相同的sqaure或不同的sqaure,如何使颜色恢复到原来的颜色

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

以下是我在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 + ")");
                }
        }
    }
}

首先将长方体的实际颜色存储在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 + ")";     
} 

并且,仅当框的颜色与实际颜色发生变化时,才使用一个布尔变量启用它。现在,如果用户单击任何其他框,则检查这些标志,如果其为真,则重置颜色。

首先将框的实际颜色存储在颜色类的对象中,假设对象名为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 + ")";     
} 
并且只在框的颜色与实际颜色发生变化时才启用一个布尔变量,现在如果用户单击任何其他框,则选中这些标志,如果其为真,则重置颜色

可以在类GridSquare的作用域上创建布尔变量。然后在gridSquare上使用此变量,单击事件处理程序,如下所示:

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
           } 
     } 
}
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 (var x = 0; x < 8; x++)
{
    for (var y = 0; y < 8; y++)
    {
        this.Controls.Add(new GridSquare(x, y, clicked));
    }
}
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);
    }
};
只需使用标签或文本框的文本属性

可以在类GridSquare的作用域上创建布尔变量。然后在gridSquare上使用此变量,单击事件处理程序,如下所示:

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
           } 
     } 
}
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 (var x = 0; x < 8; x++)
{
    for (var y = 0; y < 8; y++)
    {
        this.Controls.Add(new GridSquare(x, y, clicked));
    }
}
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);
    }
};
只需使用标签或文本框的文本属性


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

相反,我会使用回调策略

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

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
           } 
     } 
}
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 (var x = 0; x < 8; x++)
{
    for (var y = 0; y < 8; y++)
    {
        this.Controls.Add(new GridSquare(x, y, clicked));
    }
}
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);
    }
};
现在您只需要定义clicked(单击每个GridSquare时的回调),代码如下所示:

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
           } 
     } 
}
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 (var x = 0; x < 8; x++)
{
    for (var y = 0; y < 8; y++)
    {
        this.Controls.Add(new GridSquare(x, y, clicked));
    }
}
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);
    }
};
很明显,这段代码在创建网格正方形之前就开始了

这应该是比较容易理解的,但如果没有,请提问,我会详细说明


让我知道这是否适合您。

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

相反,我会使用回调策略

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

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
           } 
     } 
}
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 (var x = 0; x < 8; x++)
{
    for (var y = 0; y < 8; y++)
    {
        this.Controls.Add(new GridSquare(x, y, clicked));
    }
}
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);
    }
};
现在您只需要定义clicked(单击每个GridSquare时的回调),代码如下所示:

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
           } 
     } 
}
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 (var x = 0; x < 8; x++)
{
    for (var y = 0; y < 8; y++)
    {
        this.Controls.Add(new GridSquare(x, y, clicked));
    }
}
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);
    }
};
很明显,这段代码在创建网格正方形之前就开始了

这应该是比较容易理解的,但如果没有,请提问,我会详细说明


让我知道这是否适用于您。

这是我将原始代码添加到的内容:

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

}

这是我将原始代码添加到的内容:

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

}

我只是想了解一下,我遵循了您的逻辑,但是我发现了两个错误,第一个是您的初始代码集,最后一行显示了一个错误“clicked”名称在当前上下文中不存在。其次,从第二组代码中,它给出了一个错误chess.gridSqaure不包含接受3个参数的构造函数。@Rg786-听起来您没有从我的代码中正确复制“GridSquare”构造函数签名。它应该是“publicGridSquareIntX,IntY,ActionClicked”。我想我可能把自己弄糊涂了,我重新思考了一下,并在“GridSquareR”中添加了一个名为resetColor的方法。然后在click方法中添加了一个If语句,该语句包含resetcolor。看起来很好用。至于标签,我也重新考虑了一下,选择了ToolStripStatusLabel,它也很好用。。。到目前为止……我只是想了解一下,我遵循了你的逻辑,但是我得到了两个错误,第一个是从你的初始代码集中得到的,最后一行显示了一个错误“clicked”这个名称在当前上下文中不存在。其次,从第二组代码中,它给出了一个错误chess.gridSqaure不包含接受3个参数的构造函数。@Rg786-听起来您没有从我的代码中正确复制“GridSquare”构造函数签名。它应该是“publicGridSquareIntX,IntY,ActionClicked”。我想我可能把自己弄糊涂了,我重新思考了一下,并在“GridSquareR”中添加了一个名为resetColor的方法。然后在click方法中添加了一个If语句,该语句包含resetcolor。看起来很好用。至于标签,我也重新考虑了一下,选择了ToolStripStatusLabel,它也很好用。。。到目前为止……@Kvn-感谢您的投入,您的方式确实让我想到了其他方法来获得我所做的。请参阅第一个响应。@Kvn-感谢您的输入,您的方式确实让我想到了o
f获得我所做的事情的其他方法。请参阅第一个回复。谢谢,您的回复给了我一个在代码中设置颜色的想法。请参阅第一个响应代码谢谢,您的响应给了我一个在代码中设置颜色的想法。请参阅第一个响应代码