如何使用 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。
我正在开发一个在线西洋跳棋程序,我成功地在每个方格上绘制了棋盘和西洋跳棋。现在唯一的问题是对点击事件进行编程,我有代码响应对单个面板的点击,将背景颜色更改为蓝色,将检查器颜色更改为白色,当用户单击同一块面板时,颜色是变回原来的样子。现在我的问题是实现这个效果:: 如果用户点击 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。