dynamically adding buttons and button objects in panel - c#

private void button1_Click(object sender, EventArgs e)
{
string a = textBox1.Text;
int h = Convert.ToInt32(a);
for (int i = 0; i <= h; i++)
{
buttonArray[i] = new Button();
buttonArray[i].Size = new Size(60, 23);
buttonArray[i].Location = new Point(40,20);
panel1.Controls.Add(buttonArray[i]);
}
}
my task is if user enter 3 in text box. 3 buttons should be created dynamically and added to panel how to do that?????? i am using button array please suggest me

For example you can use this.
private void button1_Click(object sender, EventArgs e)
{
panel1.Controls.Clear();
string a = textBox1.Text;
int h = Convert.ToInt32(a);
for (int i = 0; i <= h; i++)
{
var btn = new Button {Size = new Size(60, 23), Dock=DockStyle.Left, Text=h.ToString() };
btn.Click+= delegate(object sender, EventArgs e) { //your commands };
panel1.Controls.Add(btn);
}
}

In this post already answered a similar question:
private void button1_Click(object sender, EventArgs e)
{
string a = textBox1.Text;
int h = Convert.ToInt32(a);
for (int i = 0; i <= h; i++)
{
var b = new Button { Size = new Size(60, 23), Location = new Point(4 + i * 57, 20), Text = string.Format("button{0}", i) };
b.Click += b_Click;
panel1.Controls.Add(b);
}
}
void b_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
it is desirable to test the validator to always have been a number
string a = textBox1.Text;

May be using a List is more situable?
List<Button>Buttons=new List<Buttons>();
private void button1_Click(object sender, EventArgs e)
{
Buttons.Clear();
string a = textBox1.Text;
//here should be checking if "a" is digit and is not empty
int h = Convert.ToInt32(a);
for (int i = 0; i <= h; i++)
{
Button btn=new Button();
btn.Parent=panel1;
btn.Size=new Size(60, 23);
btn.Location = new Point(40,5+25*i); //arrange verically
btn.Text = "Button "+i.ToString();
btn.Click+=btn_Click;
btn.Tag="Some Value you want to restore after button click";
Buttons.Add(btn)
}
}

Related

Labels don't move using Mouse events

I created 5 labels using a for. Inside the for I declared the properties of the labels, such as location, size, color, etc. and the possibility to move the labels using the mouse events:
private void Form1_Load(object sender, EventArgs e)
{
int alto = 100;
int ancho = 65;
for (byte fila = 0; fila < 5; fila++)
{
Label letras = new Label();
letras.Height = alto;
letras.Width = ancho;
letras.BackColor = Color.Blue;
letras.ForeColor = Color.AntiqueWhite;
letras.Font = new Font("Arial", 60);
letras.TextAlign = ContentAlignment.MiddleCenter;
letras.BorderStyle = BorderStyle.FixedSingle;
letras.Left = 200 + (ancho + 20) * fila;
letras.Top = 60;
letras.Text = null;
letras.MouseDown += new MouseEventHandler(this.letras_MouseDown);
letras.MouseMove += new MouseEventHandler(this.letras_MouseMove);
letras.MouseUp += new MouseEventHandler(this.letras_MouseUp);
this.Controls.Add(letras);
}
}
Later in the code, I create the events which will make the labels move.
private void letras_MouseDown(object sender, MouseEventArgs e)
{
mousedown = true;
}
private void letras_MouseMove(object sender, MouseEventArgs e)
{
if (mousedown)
{
letras.Location = new Point(letras.Location.X + e.Location.X, letras.Location.Y + e.Location.Y);
}
}
private void letras_MouseUp(object sender, MouseEventArgs e)
{
mousedown = false;
}
but it isn't working. Any ideas? I think that could be an Indentation problem, but I'm not sure.
The sender argument received by the letras_MouseMove method is the Label so the first thing to do is perform a cast to a usable Label object. Then simply test the static Control.MouseButtons property to determine if the Left button is currently active. You calculated the offset correctly. I believe that all you really needed was to have the correct Label object. (Of course I tested it)
Some of the code you posted is not necessary and should be removed. This shows a minimal working example.
public partial class MainForm : Form
{
public MainForm() => InitializeComponent();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// This code stays the same
int alto = 100;
int ancho = 65;
for (byte fila = 0; fila < 5; fila++)
{
Label letras = new Label();
letras.Height = alto;
letras.Width = ancho;
letras.BackColor = Color.Blue;
letras.ForeColor = Color.AntiqueWhite;
letras.Font = new Font("Arial", 60);
letras.TextAlign = ContentAlignment.MiddleCenter;
letras.BorderStyle = BorderStyle.FixedSingle;
letras.Left = 200 + (ancho + 20) * fila;
letras.Top = 60;
letras.Text = null;
letras.MouseMove += new MouseEventHandler(this.letras_MouseMove);
this.Controls.Add(letras);
}
}
// This code is different
private void letras_MouseMove(object sender, MouseEventArgs e)
{
Label letra = (Label)sender;
if(MouseButtons == MouseButtons.Left)
{
// Here, your original calculation works OK once you have the correct Label object
letra.Location = new Point(letra.Location.X + e.Location.X, letra.Location.Y + e.Location.Y);
}
}
}
Haven't tested but replace:
private void Form1_Load(object sender, EventArgs e)
{
int alto = 100;
int ancho = 65;
for (byte fila = 0; fila < 5; fila++)
{
letras = new Label();
With:
Label[] labels = Array.Empty<Label>();
private void Form1_Load(object sender, EventArgs e)
{
int alto = 100;
int ancho = 65;
for (byte fila = 0; fila < 5; fila++)
{
labels[fila] = new Label();
And replace every letras in the file with labels[(number)].

How to change properties just one button

Hey,
I have multiple buttons.I want to reduce the code so that I can set the properties of a button, but only the one I click on will change.So that I don't click on button_1 and change all the others
public static void SetProp()
{
for (int i = 0; i < buttons.Count; i++)
{
buttons[i].Image = Properties.Resources.test;
buttons[i].Width = buttons[i].Image.Width;
buttons[i].Height = buttons[i].Image.Height;
buttons[i].ImageAlign = ContentAlignment.MiddleCenter;
buttons[i].Text = null;
GraphicsPath gp = new GraphicsPath();
gp.AddEllipse(0, 0, buttons[i].Width, buttons[i].Height);
buttons[i].Region = new Region(gp);
gp.Dispose();
}
}
private void button1_Click(object sender, EventArgs e)
{
SetProp();
}
public static void SetProp(Button button)
{
for (int i = 0; i < buttons.Count; i++)
{
button.Image = Properties.Resources.test;
button.Width = buttons[i].Image.Width;
button.Height = buttons[i].Image.Height;
button.ImageAlign = ContentAlignment.MiddleCenter;
button.Text = null;
GraphicsPath gp = new GraphicsPath();
gp.AddEllipse(0, 0, button.Width, button.Height);
button.Region = new Region(gp);
gp.Dispose();
}
}
private void button1_Click(object sender, EventArgs e)
{
SetProp(sender as Button);
}

c# Picturebox Array Selection

I have created an array of picture boxes and an event for when one is clicked.
public void TicTac_Load(object sender, EventArgs e)
{
PictureBox[] PBox = new PictureBox[9];
PBox[0] = this.pictureBox1;
PBox[1] = this.pictureBox2;
PBox[2] = this.pictureBox3;
PBox[3] = this.pictureBox4;
PBox[4] = this.pictureBox5;
PBox[5] = this.pictureBox6;
PBox[6] = this.pictureBox7;
PBox[7] = this.pictureBox8;
PBox[8] = this.pictureBox9;
for (int i = 0; i < 9; i++)
{
PBox[i].Click += new System.EventHandler(PBoxes_Click);
}
}
public void PBoxes_Click(object sender, EventArgs e)
{
PictureBox myPictureBox = sender as PictureBox;
//if(Pbox[1].click){
//^^ Looking for something like this
}
My question is how can I tell which one of my pictureboxes has been clicked as i am unable to access any of them. I would just like to be able to tell which has been clicked inside the method instead of creating many.
pictureBox1_Click(object sender, EventArgs e)
Like Events
There a multiple ways to solve the issue.
You could cast sender to the correct type (here PictureBox):
public void TicTac_Load(object sender, EventArgs e)
{
PictureBox[] PBox = new PictureBox[9];
PBox[0] = this.pictureBox1;
PBox[1] = this.pictureBox2;
PBox[2] = this.pictureBox3;
PBox[3] = this.pictureBox4;
PBox[4] = this.pictureBox5;
PBox[5] = this.pictureBox6;
PBox[6] = this.pictureBox7;
PBox[7] = this.pictureBox8;
PBox[8] = this.pictureBox9;
for (int i = 0; i < 9; i++)
{
PBox[i].Click += new System.EventHandler(PBoxes_Click);
}
}
public void PBoxes_Click(object sender, EventArgs e)
{
PictureBox myPictureBox = sender as PictureBox;
}
Alternatively (less-recommended), you could move PBox to a class-level array:
PictureBox[] PBox = new PictureBox[9];
public void TicTac_Load(object sender, EventArgs e)
{
PBox[0] = this.pictureBox1;
PBox[1] = this.pictureBox2;
PBox[2] = this.pictureBox3;
PBox[3] = this.pictureBox4;
PBox[4] = this.pictureBox5;
PBox[5] = this.pictureBox6;
PBox[6] = this.pictureBox7;
PBox[7] = this.pictureBox8;
PBox[8] = this.pictureBox9;
for (int i = 0; i < 9; i++)
{
PBox[i].Click += new System.EventHandler(PBoxes_Click);
}
}
public void PBoxes_Click(object sender, EventArgs e)
{
PictureBox myPictureBox = PBox[PBox.indexOf(sender)];
}

Select part of Button's text

I'm using this code to create buttons with two lines text
private void button1_Click(object sender, EventArgs e)
{
int top = 50;
int left = 100;
int n = 0;
int s = 99;
for (int i = 0; i < 20; i++)
{
Button button = new Button();
button.Left = left;
button.Top = top;
panel1.Controls.Add(button); // here
button.Size = new Size(50, 50);
if (i == 4 || i == 9||i==14||i==19)
{
top = 30;
left = 23;
top +=button.Top+2;
left += button.Width+2;
}
else
left += button.Width + 2;
n = n + 1;
s = s + 1;
button.Text = Convert.ToString(n) + Environment.NewLine + Convert.ToString(s);
button.Click += Button_Click;
}
}
private void Button_Click(object sender, EventArgs e)
{
string s;
Button button = (Button)sender;
s = button.Text + Environment.NewLine;
MessageBox.Show(s);
}
So I need to select only second line brom my button text when I click dynamic button. How will I do this?
you can store some data in Tag property:
button.Text = Convert.ToString(n) + Environment.NewLine + Convert.ToString(s);
button.Tag = new int[] { n, s };
and later retrive it and use:
private void Button_Click(object sender, EventArgs e)
{
Button button = (Button)sender;
var data = button.Tag as int[];
string s = data[1].ToString();
MessageBox.Show(s);
}
private void Button_Click(object sender, EventArgs e)
{
string s;
Button button = (Button)sender;
s = button.Text + Environment.NewLine;
MessageBox.Show(button.Text.Split(new[] { Environment.NewLine }, StringSplitOptions.None)[1]);
}

Sending a variable in a C# EventHandler?

How can I send a variable with a newly created EventHandler?
The code I have is something like:
for (int i = 0; i < 5; i++)
{
Button buttonX = new Button();
buttonX.Location = new Point(0, 0 + offset);
buttonX.Size = new Size(310, 48);
buttonX.Click += new EventHandler(buttonClick);
}
private void buttonClick(object sender, EventArgs e)
{
MessageBox.Show();
}
How can I can make it like
buttonX.Click += new EventHandler(buttonClick , i);
private void buttonClick(object sender, EventArgs e, int i)
{
MessageBox.Show(i.toString());
}
Closures are grand. You can use lambda notation:
buttonX.Click += (sender, e) => buttonClick(sender, e, i);
or anonymous delegate notation:
buttonX.Click += delegate (object sender, EventArgs e) { buttonClick(sender, e, i); };
However, you're going to have trouble if you capture the loop variable.
Instead, do
for (int i = 0; i < 5; i++)
{
Button buttonX = new Button();
buttonX.Location = new Point(0, 0 + offset);
buttonX.Size = new Size(310, 48);
var i_copy = i;
buttonX.Click += (sender, e) => buttonClick(sender, e, i_copy);
}
Given your scenario, just utilize the Tag property; don't mix the solution with the Click event; you don't need to "pass" i every time to the event; just tag it to the control since it's always the same; that way you don't have to worry about closure.
Change your code to this:
for (int i = 0; i < 5; i++)
{
Button buttonX = new Button();
buttonX.Location = new Point(0, 0 + offset);
buttonX.Size = new Size(310, 48);
buttonX.Click += new EventHandler(buttonClick);
buttonX.Tag = i;
}
private void buttonClick(object sender, EventArgs e)
{
MessageBox.Show(((Button)sender).Tag.ToString());
}
You would create a class derived from EventArgs that carries the additional data points that you want.
http://msdn.microsoft.com/en-us/library/system.eventargs.aspx
So instead of just using EventArgs you would create an EventArgs for the event you are raing.
public class ButtonClickedEventArgs : EventArgs
{
public int EventInteger { get; private set; }
public ButtonClickedEventArgs(int i)
{
EventInteger = i;
}
}
And then when you raise the event you would create the ButtonClickedEventArgs class and pass that with the EventHandler.
You can't do that, but what you can do is use an intermediate lambda:
for (int i = 0; i < 5; i++)
{
int j = i; // Need to do this to fix closure issue
Button buttonX = new Button();
buttonX.Location = new Point(0, 0 + offset);
buttonX.Size = new Size(310, 48);
buttonX.Click += (sender, e) => {
buttonClick(sender, e, j);
};
}
private void buttonClick(object sender, EventArgs e, int i)
{
MessageBox.Show(i.toString());
}

Categories