如何使用 C# 管理对面板数组的点击事件?

How to manage click events made to an array of panels with C#?

我正在开发一个在线西洋跳棋程序,我成功地在每个方格上绘制了棋盘和西洋跳棋。现在唯一的问题是对点击事件进行编程,我有代码响应对单个面板的点击,将背景颜色更改为蓝色,将检查器颜色更改为白色,当用户单击同一块面板时,颜色是变回原来的样子。现在我的问题是实现这个效果:: 如果用户点击 panelA 然后应用颜色变更,当点击不同的 panelB 时应用到 panelA 的颜色应该恢复到原来的颜色,就像在双击效果.

我尝试的解决方案

我初始化了一个 List<Panel> clicked_objects 对象并用它来存储被单击的 Panel 元素,我希望列表对象的计数会随着每次连续单击而增加,但是当我执行 MessageBox.Show(clicked_objects.Count.ToString()),一直显示1。 我需要这样做,以便立即将第二次单击的 Panel 添加到此列表中,我可以在 index 1(new Panel) 处检查面板的计数和颜色,并在 index 0(previously clicked Panel) 处使面板脱色。我怎样才能做到这一点?单击一个面板会删除先前单击的元素上的颜色(如果有)吗?

代码

public class Checkerpiece
    { 
        //declare a panel array for storing clicked Panels
        List<Panel> clicked_squares=new List<Panel>();
        //The object above can only hold two panel elements
        //colors of the rounded pieces
        Color color;
        //specify where the checker is drawn
        Panel target_square;
        //specify the center of the circle
        float center_x;
        float center_y;
        //specify the radius of the checker piece
        float radii;
        //define some foreground color that will be used to access the color of the checker
        Color foreground;
        //fill the details inside the constructor
        public Checkerpiece(Panel mypanel,Color color)
        {
            this.color = color;
            this.target_square = mypanel;
            this.center_x = mypanel.Width / 2;
            this.center_y = mypanel.Height / 2;
            this.radii = mypanel.Width / 2;
            //register an onclick listener for our checkerpiece object
            this.target_square.Click += Target_square_Click;
           // this.target_square.MouseClick += Target_square_MouseClick;
        }

      
        private void Target_square_Click(object sender, EventArgs e)
        {
            clicked_squares.Add(target_square);
           //this keeps showing 1 no mater what panel I click
            MessageBox.Show(clicked_squares.Count.ToString());
         }
          public static void fillCircle(Graphics g, Brush b, float centerX, float centerY, float radius)
        {
            g.FillEllipse(b, centerX - radius, centerY - radius,
                     radius + radius, radius + radius);
        }
        //implement a getter for the color used to used to draw the checker
        public Color getCheckerColor()
        {
            return this.color;
        }
  }

棋盘class

public partial class Form1 : Form
    {
        private Panel[,] _chessBoardPanels;
        public Form1()
        {
            InitializeComponent();
            
        }
      
       
        private void Form1_Load(object sender, EventArgs e)
        {
            const int tileSize = 100;
            const int gridSize = 8;
            var clr1 = Color.DarkGray;
            var clr2 = Color.White;

            // initialize the "chess board"
            _chessBoardPanels = new Panel[gridSize, gridSize];
            int count = 0;
            // double for loop to handle all rows and columns
            for (var n = 0; n < gridSize; n++)
            {
                for (var m = 0; m < gridSize; m++)
                {
                    // create new Panel control which will be one 
                    // chess board tile
                    var newPanel = new Panel
                    {
                        Size = new Size(tileSize, tileSize),
                        Location = new Point(tileSize * n, tileSize * m)
                      
                };
                    //register an event listener for each square

                   
                    // add to Form's Controls so that they show up
                    Controls.Add(newPanel);

                    // add to our 2d array of panels for future use
                    _chessBoardPanels[n, m] = newPanel;
                    //draw only the red checkers on top of the board
                    
                    // color the backgrounds
                    if (n % 2 ==0)
                        newPanel.BackColor = m % 2 != 0 ? clr1 : clr2;
                        //new Checkerpiece(newPanel, Color.Red).draw();
                    
                    else
                        newPanel.BackColor = m % 2 != 0 ? clr2 : clr1;
                    //draw a new checker piece
                    if (newPanel.BackColor==Color.White &&m<=3)
                        new Checkerpiece(newPanel, Color.Red).draw(); 
                       ;
                    if (newPanel.BackColor == Color.White && m > 4)
                        new Checkerpiece(newPanel, Color.Black).draw();
               
                }
            }
           
        }
}

输出

当我点击一个作品时,每种颜色都保留在之前点击的项目上,这不应该是这种情况

目标

如何存储单击面板的状态并在单击新面板时恢复?

你应该从棋盘上管理棋子class,棋子列表可以通过它们的引用来检查,当你通过点击事件。使用板(窗体)class 管理当前选定的部分并在设置这些属性时处理 Select/Deselect。