Does somebody know how to programmatically generate a grid of checkboxes like this using a 2D Array?
for (int x = 0; x < numberOfRows; x++)
{
for (int y = 0; y < numberOfColumns; y++)
{
int index = x * numberOfColumns + y;
var checkbox = new CheckBox();
checkbox.Location = new Point(20 * x, 20*y);
this.Controls.Add(checkbox);
}
}
Give this a go. You need to initialise a dictionary, as shown here at the top, to allow for the GetCheckBoxAtPosition function to work.
private Dictionary<Point, CheckBox> checkBoxes;
private Dictionary<Point,CheckBox> GenerateCheckBoxes(Form form, int width, int height, int padding) {
Dictionary<Point, CheckBox> checkboxes = new Dictionary<Point, CheckBox>();
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
CheckBox checkBox = new CheckBox();
Point location = new Point(x*(15+padding), y*(15+padding));
//Formatting
checkBox.Location = location;
checkBox.Text = string.Empty;
checkBox.Size = new Size(15,15);
//Custom behaviour
checkBox.Click += CheckBox_Click;
form.Controls.Add(checkBox);
checkboxes.Add(new Point(x, y), checkBox);
}
}
return checkboxes;
}
private void CheckBox_Click(object sender, EventArgs e)
{
CheckBox clicked = (CheckBox)sender;
}
private CheckBox GetCheckBoxAtPosition(int x, int y) {
return checkBoxes[new Point(x, y)];
}
You could use a List of Lists, like this:
private List<List<CheckBox>> CheckBoxes = new List<List<CheckBox>>();
private void button1_Click(object sender, EventArgs e)
{
int numberOfRows = 5;
int numberOfColumns = 10;
CheckBoxes.Clear();
for (int y = 0; y < numberOfRows; y++)
{
List<CheckBox> row = new List<CheckBox>();
CheckBoxes.Add(row);
for (int x = 0; x < numberOfColumns; x++)
{
var checkbox = new CheckBox();
checkbox.Text = "";
checkbox.AutoSize = true;
checkbox.Location = new Point(20 * x, 20 * y);
row.Add(checkbox);
this.Controls.Add(checkbox);
}
}
}
Then you could access a particular one with:
CheckBoxes[0][3].Checked = true;
I just found the Answer the Problem was the Autosize without Autosize=true some Checkboxes will not be visible
CheckBox[,] c = new CheckBox[2, 2];
for (int i = 0; i < c.GetLength(0); i++)
{
for (int j = 0; j < c.GetLength(1); j++)
{
c[i, j] = new CheckBox();
c[i, j].Location = new Point(i*20, j* 20);
c[i, j].AutoSize = true;
//c[i, j].Height = 10;
//c[i, j].Width = 10;
this.Controls.Add(c[i, j]);
}
}
Related
I am fairly new to C# and I can't figure out how to create an array with visible picture boxes inside the cs file. In this example I want to create 200 picture boxes 10x20 to create an grid for a tetris game. This is my code, I can't get any of the pictures to show but the code runs just fine.
Image[] blockImage = {
TetrisSlutprojekt.Properties.Resources.TileEmpty,
TetrisSlutprojekt.Properties.Resources.TileCyan,
TetrisSlutprojekt.Properties.Resources.TileBlue,
TetrisSlutprojekt.Properties.Resources.TileRed,
TetrisSlutprojekt.Properties.Resources.TileGreen,
TetrisSlutprojekt.Properties.Resources.TileOrange,
TetrisSlutprojekt.Properties.Resources.TilePurple,
TetrisSlutprojekt.Properties.Resources.TileYellow
};
PictureBox[] blockBoxes = new PictureBox[200];
private void CreateBoxes()
{
for (int i = 0; i < blockBoxes.Length; i++)
{
blockBoxes[i] = new System.Windows.Forms.PictureBox();
blockBoxes[i].Name = "pbBox" + i;
blockBoxes[i].Size = new Size(30, 30);
blockBoxes[i].Visible = true;
}
}
private void PlaceBoxes()
{
for (int y = 0; y < rows; y++)
{
for (int x = 0; x < columns; x++)
{
blockBoxes[y].Top = y * blockWidth;
blockBoxes[x].Left = x * blockWidth;
}
}
}
private void FillBoxes()
{
for (int i = 0; i < blockBoxes.Length; i++)
{
blockBoxes[i].Image = blockImage[4];
}
}
Add them to the Form:
private void CreateBoxes()
{
for (int i = 0; i < blockBoxes.Length; i++)
{
blockBoxes[i] = new System.Windows.Forms.PictureBox();
blockBoxes[i].Name = "pbBox" + i;
blockBoxes[i].Size = new Size(30, 30);
blockBoxes[i].Visible = true;
this.Controls.Add(blockBoxes[i]); // <--- HERE
}
}
Basically, I need to match to match the Picture and the color, so that result will be that whenever I press the burger it becomes blue, and when I click something else it becomes green.
NOW it just randomly goes green or blue whenever I click the button with no reliance on the clicked picture.
Again, I need to match to match the picture and the color, so that result will be that whenever I press the burger it becomes blue, and when I click something else it becomes green.
I will now add screenshots of the form when it starts and what happens, and the entire code.
Thanks in advance.
Start : https://prnt.sc/jnad9j
When Clicked : https://prnt.sc/jnadie
CODE:
for (int i = 0; i < arr.GetLength(0); i++)
{
cx = x;
for (int j = 0; j<arr.GetLength(1); j++)
{
value = rnd.Next(0, 2);
t = new Button();
t.Tag = new Place(i, j);
if (value == 0)
rndmimg = rnd.Next(1, 2);
else rndmimg = rnd.Next(2, 6);
t.BackColor = Color.Red;
t.BackgroundImageLayout = ImageLayout.Stretch;
t.BackgroundImage = Image.FromFile("..\\..\\Pictures\\"+rndmimg+".png");
t.Bounds = new Rectangle(cx, y, w, h);
t.Click += new System.EventHandler(this.qqq_Click);
this.Controls.Add(t);
arr [i, j] = t;
cx += w;
}
y += h;
}
public Form1() => InitializeComponent();
private void Form1_Load(object sender, EventArgs e) => rnd = new Random();
private void qqq_Click(object sender, EventArgs e)
{
int px;
int py;
Place pl = (Place)(((Button)sender).Tag);
px = pl.GetR();
py = pl.C;
rndmcus = rnd.Next(0, 2); // Rndmcus determines color when button is clicked
if (rndmcus == 0)
{
mishvalue = 0;
arr[px, py].BackColor = Color.Green;
arr[px, py].Enabled = false;
}
if (rndmcus == 1)
{
mishvalue = 1;
arr[px, py].BackColor = Color.Blue;
arr[px, py].Enabled = false;
}
((Button)sender).Text = " ";
scanner();
}
public void scanner()
{
int counter = 0;
for (int i = 0; i < arr.GetLength(0); i++)
for (int j = 0; j < arr.GetLength(0); j++)
if (arr[i, j].Text == " ")
counter++;
if (counter == boardsize * boardsize)
this.Close();
}
class Place
{
private int r;
private int c;
public Place(int r, int c)
{
this.r = r;
this.c = c;
}
public int GetR() => r;
public int C => c;
public void SetR(int r) => this.r = r;
public void SetC(int c) => this.c = c;
}
Assign all your button an id then access it in the event
for (int j = 0; j < arr.GetLength(1); j++)
{
value = rnd.Next(0, 2);
t = new Button();
t.ID = j.ToString();
Button button = (Button)sender;
string buttonId = button.ID;
Associate color with the id in like a Dictionary.
I have a Windows Forms application and I'm trying to add buttons to mimic a calculator.
public class myform : Form
{
public myform()
{
//setting size of form
this.Text = "Calculator";
this.Height = 600;
this.Width = 400;
//creating buttons from 0-9
Button[] b = new Button[10];
int x = 0;
int y = 0;
string ch;
for (int i = 0; i < b.Length; i++)
{
ch = Convert.ToString(i);
x = 0;
y = y + 50;
b[i] = new Button();
b[i].Height = 40;
b[i].Width = 40;
b[i].Text = ch;
for (int j = 0; j < 3; j++)
{
x = x + 50;
b[i].Location = new Point(x, y);
}
}
for (int i = 0; i < b.Length; i++)
{
this.Controls.Add(b[i]);
}
}
}
here is the form class in which i am creating the object of myform class described above.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
myform mf = new myform();
mf.Show();
}
}
The problem seems to be that you always set the x value to x = x + 150; I suggest you change your x value to x = (i%3) * 50; and your y to y= (i/3) *50;
that should provide you with a nice array of buttons.
ch = Convert.ToString(i);
x = (i%3)*50;
y = (i/3)*50;
b[i] = new Button();
b[i].Height = 40;
b[i].Width = 40;
b[i].Text = ch;
b[i].Location = new Point(x, y);
Will be your new loop body.
I tried many versions, but most of the tutorials are made for wpf apps.
Anyway, I can make some kind of grid, but some buttons are out of the form, and the spaceng among them is too large (And of course, if I resize the form, the grid still in the same size).
Here's on of my tries, which isn't works correctly:
int size = 32;
_buttonGrid = new Button[size, size];
for (Int32 i = 0; i < size; i++)
for (Int32 j = 0; j < size; j++)
{
_buttonGrid[i, j] = new Button();
_buttonGrid[i, j].Location = new Point( size * j, size * i);
_buttonGrid[i, j].Size = new Size(flowLayoutPanel1.Width / size, flowLayoutPanel1.Height / size);
_buttonGrid[i, j].Font = new Font(FontFamily.GenericSansSerif, 6, FontStyle.Bold);
_buttonGrid[i, j].Enabled = true;
_buttonGrid[i, j].TabIndex = 10 + i * size + j;
_buttonGrid[i, j].FlatStyle = FlatStyle.Flat; stÃpus
flowLayoutPanel1.Controls.Add(_buttonGrid[i, j]);
}
You can use TableLayoutPanel with columns and rows and put your buttons in it.
For example, add a TableLayoutPanel to your form and put this code in Load event of form:
private void Form_Load(object sender, EventArgs e)
{
var rowCount = 10;
var columnCount = 10;
this.tableLayoutPanel1.ColumnCount = columnCount;
this.tableLayoutPanel1.RowCount = rowCount;
this.tableLayoutPanel1.ColumnStyles.Clear();
this.tableLayoutPanel1.RowStyles.Clear();
for (int i = 0; i < columnCount; i++)
{
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100 / columnCount ));
}
for (int i = 0; i < rowCount; i++)
{
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100 / rowCount ));
}
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < columnCount; j++)
{
var button = new Button();
button.Text = string.Format("{0}{1}", i, j);
button.Name = string.Format("button_{0}{1}", i, j);
button.Dock = DockStyle.Fill;
this.tableLayoutPanel1.Controls.Add(button, j, i);
}
}
}
I am currently trying to develop a form of battleships on c# windows form.
Here is the code I am trying to use.. the trouble I have been having is how to create a second set of buttons (another 10x10) behind the other, with two sets of controls so I can switch between the two.
I have everything like AI and automated setups, I just need to have 2 button controls. I hope someone can help me out with this! Many thanks!
private List<List<Button>> grid = new List<List<Button>>();
public UserForm()
{
InitializeComponent();
byte numRows = 10;
byte numCols = 10;
for (byte i = 0; i < numRows; i++)
{
grid.Add(ButtonRowCreator(numCols, 25, (i+1) * 50));
}
}
public List<Button> ButtonRowCreator(byte numOfBtnsNeeded, int x, int y)
{
List<Button> btns = new List<Button>();
for (int i = 0; i < numOfBtnsNeeded; i++)
{
Button btn = new Button();
btn.Size = new Size(50, 50);
btn.Location = new Point(x + (i * btn.Width), y);
btns.Add(btn);
btn.Font = new Font("Georiga", 10);
this.Controls.Add(btn);
btn.Click += new EventHandler(btn_Click);
}
return btns;
}
void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
int curRow = -1, curCol = -1;
for(int i = 0; i < grid.Count; i++)
{
int index = grid[i].IndexOf(btn);
if (index != -1)
{
curRow = i;
curCol = index;
Console.WriteLine("curRow = " + curRow.ToString() + ", curCol = " + curCol.ToString());
}
}
// ... now you can use "curRow", "curCol" and "grid" to do something ...
foreach (List<Button> row in grid)
{
foreach (Button col in row)
{
col.ForeColor = Color.Gray;
}
}
if (board[curRow, curCol] == 1)
{
if (btn.Text == "Hit")
{
}
else
{
btn.Text = "Hit";
btn.BackColor = Color.Red;
hit++;
}
if (hit == 17)
{
MessageBox.Show("Congratulations, You Sunk Their Battleships!");
MessageBox.Show("Thanks For Playing!");
MessageBox.Show("Goodbye!");
}
}
else
{
btn.Text = "Miss!";
btn.BackColor = Color.Blue;
}
I think this is what you're after?
It looks like a lot of your code is used to figure out what button is clicked on. This information can be stored on the button object itself in the Tag property and greatly simplifies the code.
private Button[,] _grid1;
private Button[,] _grid2;
public UserForm()
{
InitializeComponent();
_grid1 = new Button[10, 10];
_grid2 = new Button[10, 10];
CreateGrid(_grid1, 10, 10, 25, 0, 20, true);
CreateGrid(_grid2, 10, 10, 25, 250, 20, false);
}
public void CreateGrid(Button[,] grid, int numOfRows, int numOfCols, int offsetX, int offsetY, int buttonSize, bool enabled)
{
for (byte i = 0; i < numOfRows; i++)
{
for (byte j = 0; j < numOfCols; j++)
{
grid[i,j] = ButtonCreator(i, j, offsetX, offsetY, buttonSize, enabled);
}
}
}
public Button ButtonCreator(int row, int col, int x, int y, int buttonSize, bool enabled)
{
Button btn = new Button();
btn.Size = new Size(buttonSize, buttonSize);
btn.Location = new Point(x + (col * buttonSize), y + (row * buttonSize));
btn.Font = new Font("Georiga", 10);
this.Controls.Add(btn);
btn.Click += new EventHandler(btn_Click);
btn.Tag = row + "," + col;
btn.Enabled = enabled;
return btn;
}
void btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
string[] coord = btn.Tag.ToString().Split(',');
int curRow = Convert.ToInt32(coord[0]);
int curCol = Convert.ToInt32(coord[1]);
Console.WriteLine(curRow = " + curRow + ", curCol = " + curCol);
// ... now you can use "curRow", "curCol" to do something ...
_grid1[curRow, curCol].BackColor = Color.Red;
}