I have a dictionary of buttons and also an null variable button. When you click on an button from the dictionary, we get the values that should be sent to an empty variable.
public static Button selectedfigure=null;
public Dictionary<(int x, int y), Button> _Panels = new Dictionary<(int x, int y), Button>();
public void Fillboard()
{
for (int x = 0; x < 8; x )
{
for (int y = 0; y < 8; y )
{
_Panels[(x, y)] = new Button()
{
Height = 64,
Width = 64,
Location = new Point(x * 64, y * 64),
BackColor = CalculateBackColor(x,y),
BackgroundImage = CalculateBackimage(x,y)
};
Controls.Add(_Panels[(x, y)]);
}
}
}
CodePudding user response:
Your question is about how to interact with Mouse events on your "board". The answer is to subscribe to Mouse events like Click
for each control you add. Your code is using a normal Button
but will be much simpler if you make a custom class that inherits Button
or preferably PictureBox
and this way each instance keeps track of its own X-Y, color, and image.
Also, instead of using a Dictionary
lookup and setting Location
properties yourself, you might try an 8x8 TableLayoutPanel
for the board, then iterate all its 8 columns and rows with methods that take column
and row
as arguments.
The mouse events will now be be subscribed to in the addSquare
method.
private void addSquare(int column, int row)
{
var color = ((column row) % 2) == 0 ? Color.White : Color.Black;
var square = new Square
{
BackColor = color,
Column = column,
Row = row,
Size = new Size(80, 80),
Margin = new Padding(0),
Padding = new Padding(10),
Anchor = (AnchorStyles)0xf,
SizeMode = PictureBoxSizeMode.StretchImage,
};
tableLayoutPanel.Controls.Add(square, column, row);
// Hook the mouse events here
square.Click = onSquareClicked;
square.MouseHover = onSquareMouseHover;
}
Before and after iterating the TableLayoutPanel
with addSquare
Changing the value of the enum Piece { None, Black, Red }
property can choose an image accordingly.
private void initImage(int column, int row)
{
var square = (Square)tableLayoutPanel.GetControlFromPosition(column, row);
switch (row)
{
case 0:
case 1:
square.Piece = Piece.Black;
break;
case 6:
case 7:
square.Piece = Piece.Red;
break;
default:
square.Piece = Piece.None;
break;
}
}
Before and after iterating the TableLayoutPanel
with initImage
Mouse
event handlers are simple now:
private void onSquareClicked(object sender, EventArgs e) =>
MessageBox.Show($"Clicked: {sender}");
private void onSquareMouseHover(object sender, EventArgs e) =>
_tt.SetToolTip((Control)sender, sender.ToString());
ToolTip _tt = new ToolTip();
The Square
class is uncomplicated, just a few lines of code.
class Square : PictureBox // Gives more visual control than Button
{
public int Column { get; internal set; }
public int Row { get; internal set; }
Piece _piece = Piece.None;
public Piece Piece
{
get => _piece;
set
{
if(!Equals(_piece, value))
{
_piece = value;
switch (_piece)
{
case Piece.None:
Image = null;
break;
case Piece.Black:
Image = Resources.black;
break;
case Piece.Red:
Image = Resources.red;
break;
}
}
}
}
public override string ToString() =>
Piece == Piece.None ?
$"Empty {BackColor.Name} square [column:{Column} row:{Row}]" :
$"{Piece} piece [column:{Column} row:{Row}]";
}
Edited (in response to Jeremy's excellent suggestion)
Where and how to call the methods to initialize the board:
public MainForm()
{
InitializeComponent();
// Board is a TableLayoutPanel 8 x 8
tableLayoutPanel.AutoSize = true;
tableLayoutPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
// Add squares
IterateBoard(addSquare);
// Add pieces
IterateBoard(initImage);
}
void IterateBoard(Action<int, int> action)
{
for (int column = 0; column < 8; column )
{
for (int row = 0; row < 8; row )
{
action(column, row);
}
}
}
CodePudding user response:
I don't know exactly which is your problem. I think you need know which button is pressed in your matrix.
You can add the controls in the same way but instead the use of _Panels
dictionary, you can use Tag
property of button to store a Point
with the x,y coordinates:
for (int x = 0; x < 8; x )
{
for (int y = 0; y < 8; y )
{
var button = new Button
{
Height = 64,
Width = 64,
Location = new Point(x * 64, y * 64),
BackColor = CalculateBackColor(x,y),
BackgroundImage = CalculateBackimage(x,y),
Tag = new Point(x, y)
};
button.Click = OnButtonClick;
Controls.Add(button);
}
}
In the click event handler of the button:
private void OnButtonClick(object sender, EventArgs e)
{
var button = (Button)sender;
var point = (Point)button.Tag;
// Here you have x,y coordinates of clicked button
}