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.
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.
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]);
}
}
public partial class Window2 : Window
{
int margin = 200;
public Window2()
{
this.InitializeComponent();
for (int i = 1; i <= 5; i++)
{
TextBlock DynamicLine = new TextBlock();
DynamicLine.Name = "lbl_DynamicLine" + i;
DynamicLine.Width = 600;
DynamicLine.Height = 20;
DynamicLine.Text =i+"Dynamic TextBlock";
DynamicLine.Margin = new Thickness(50, margin, 0, 0);
margin = margin + 20;
LayoutRoot.Children.Add(DynamicLine);
}
}
}
I tried to remove the textblock dynamically like below.
LayoutRoot.Children.Remove(DynamicLine);
But i can remove the last created textblock only with above code line.Now i want to remove all textblock dynamically. what should i do for that.
try this code
public partial class Window2 : Window
{
int margin = 200;
TextBlock DynamicLine;
public Window2()
{
this.InitializeComponent();
for (int i = 1; i <= 5; i++)
{
DynamicLine = new TextBlock();
DynamicLine.Name = "lbl_DynamicLine" + i;
RegisterName(DynamicLine.Name, DynamicLine);
DynamicLine.Width = 600;
DynamicLine.Height = 20;
DynamicLine.Text =i+"Dynamic TextBlock";
DynamicLine.Margin = new Thickness(50, margin, 0, 0);
margin = margin + 20;
LayoutRoot.Children.Add(DynamicLine);
}
for (int i = 1; i <= 5; i++)
{
DynamicLine = (TextBlock)this.FindName("lbl_DynamicLine" + i);
LayoutRoot.Children.Remove(DynamicLine);
}
}
}
To delete all children, you should call the clear method.
LayoutRoot.Children.Clear();
for (int i = LayoutRoot.Children.Count; i > 0; i--)
{
LayoutRoot.Children.RemoveAt(i-1);
}
I have a MyControl class. Inside MyClass object there are textboxes and a checkbox.
I am trying to add a checkbox event handler, but it does not work. What can be the problem?
private List<MyControls> _myControls = new List<MyControls>();
MyControls mc = new MyControls();
public void CreateFormElements(int i, StringReader sr)
{
ProductForm form2 = new ProductForm();
form2.Visible = true;
form2.Activate();
String line = "";
for (int n = 0; n < i; n++)
{
line = sr.ReadLine();
mc = new MyControls();
if (line.Length > 3)
{
String[] _line = line.Split(new char[] { '\t' });
mc.SetY(30 + n * 20);
mc.initElements(_line, n);
_myControls.Add(mc);
**mc.cb.CheckedChanged += cb_CheckedChanged;**
}
}
}
private void cb_CheckedChanged(Object sender, EventArgs e)
{
string NameSet = (sender as CheckBox).Name.Split(new char[]{'_'})[1];
MessageBox.Show(NameSet);
}
Here is the code of MyControls Class:
class MyControls
{
int x=5;
int y=30;
public CheckBox cb = new CheckBox();
public TextBox tb1 = new TextBox();
public TextBox tbSpecs = new TextBox();
public TextBox tb3 = new TextBox();
public TextBox tb4 = new TextBox();
public void initElements(String[] name, int i)
{
cb.Width = 10;
cb.Height = 10;
cb.Name = "cb_" + i.ToString();
cb.Location = new Point(x, y+5);
cb.Checked = false;
Form.ActiveForm.Controls.Add(cb);
x += 15;
tb1.Width = 50;
tb1.Height = 20;
tb1.Location = new Point(x, y);
tb1.Name = "tb1_" + i.ToString();
tb1.Text = name[0];
Form.ActiveForm.Controls.Add(tb1);
x += 60;
tbSpecs.Width = 150;
tbSpecs.Height = 20;
tbSpecs.Name = "tb2_" + i.ToString();
tbSpecs.Text = name[1];
tbSpecs.Location = new Point(x, y);
Form.ActiveForm.Controls.Add(tbSpecs);
x += 160;
tb3.Width = 40;
tb3.Height = 20;
tb3.Name = "tb3_" + i.ToString();
tb3.Text = name[2];
tb3.Location = new Point(x, y);
Form.ActiveForm.Controls.Add(tb3);
x += 50;
tb4.Width = 450;
tb4.Height = 20;
tb4.Name = "tb4_" + i.ToString();
tb4.Text = name[3];
tb4.Location = new Point(x, y);
Form.ActiveForm.Controls.Add(tb4);
x = 0;
}
public int SetX(int X)
{
x = X;
return x;
}
public int SetY(int Y)
{
y = Y;
return y;
}
}
mc.cb.CheckedChanged += new System.EventHandler(this.cb_CheckedChanged)
A few points to check in CreateFormElements(int i, StringReader sr){...}:
Is i greater than zero? If not the loop will never run and the event handler will never get attached.
Is line.Length ever greater than zero? If not you'll never get inside the if-block and the handler won't get attached.