Get the number of a certain Button in stack panel - c#

Hey I would like to create a stack panel with multiple buttons in it and when I press one, it tells me which button it is. Like when I press the second button from the top, I get the number 2 back and so on.
The buttons are created with this loop:
for (int i = 0; i < LBresponse.Items.Count; i++)
{
System.Windows.Controls.Button BTclear = new Button();
BTclear.Content = "Clear";
BTclear.Width = 50;
BTclear.Height = 20;
BTclear.HorizontalAlignment = HorizontalAlignment.Right;
BTclear.Click += Button_Click;
BTclear.IsEnabled = true;
STPresponse.Children.Add(BTclear);
}
I could do it with the location of the button but I hope there is a better solution.
One Idea would be to put the number into the context when the button is created but this would not be pretty.

You could store the number or index somewhere, for example in the Tag property:
for (int i = 0; i<LBresponse.Items.Count; i++)
{
System.Windows.Controls.Button BTclear = new Button();
BTclear.Tag = i;
BTclear.Content = "Clear";
BTclear.Width = 50;
BTclear.Height = 20;
BTclear.HorizontalAlignment = HorizontalAlignment.Right;
BTclear.Click += (ss, ee) =>
{
MessageBox.Show(((Button)ss).Tag.ToString());
};
BTclear.IsEnabled = true;
STPresponse.Children.Add(BTclear);
}

Related

Creating a new control property for certain amount of time in C# Winform

Say if I want to create a multiple button on my form based on a loop value of 3 then 3 buttons should be created into that form, in my case I have this textbox input that should determine the loop value on button click. What I've tried:
void Button4Click(object sender, EventArgs e)
{
int get_col_range = Convert.ToInt32(textBox3.Text);
for(int i=0; i<get_col_range; i++) {
Button btn = new Button();
btn.Text = Convert.ToString(i);
this.Controls.Add(btn);
}
}
I put on value of 2 on the TextBox input as test value but turned out that nothing happened why?.
Try the following on a form with no controls in a button click event.
int top = 10;
int heightPadding = 30;
for (int index = 0; index < 3; index++)
{
var button = new Button()
{
Text = $"Button {index}",
Name = $"Button{index}",
Location = new Point(10, top)
};
Controls.Add(button);
top += heightPadding;
}

How to get position of a button in an array on mouse clicked

I have the code that creates a grid of buttons from an array. I need to get their possitions in array on mouse clicked event. Any ideas or links to some other post/articles would be very helpful.
The code for creating the grid:
// Creating buttons array for 5x5 grid
Button[] tiles25 = new Button[25];
// Generating 5x5 button grid
void Spawn5x5Grid()
{
// position of the firts tile
int x = 35, y = 55;
// current tile index
int count = 0;
for (int i = 1; i < 6; i++)
{
for (int j = 1; j < 6; j++)
{
// Adding button to the array
tiles25[count] = new Button()
{
Size = new Size(24, 24),
Location = new Point(x, y)
};
// Adding buttons from array to the form
Controls.Add(tiles25[count]);
count++;
x = x + 24;
}
x = 35;
y = y + 24;
}
lblSize.Text = "5 x 5";
currentGrid = Grids.grid5x5;
}
I suggest scanning tiles25 array in the Click event handler
...
Controls.Add(tiles25[count]);
tiles25[count].Click += (o, ee) => {
Button button = o as Button;
int index = Array.IndexOf(tiles25, button);
//TODO: Put relevant code here: "button" clicked which is at "index" position
};
count++;
x = x + 24;
...
Register an event handler for each of your button click events and then extract the Location property from the sender object:
// Generating 5x5 button grid
void Spawn5x5Grid()
{
// position of the firts tile
int x = 35, y = 55;
// current tile index
int count = 0;
for (int i = 1; i < 6; i++)
{
for (int j = 1; j < 6; j++)
{
// Adding button to the array
tiles25[count] = new Button()
{
Size = new Size(24, 24),
Location = new Point(x, y)
};
// Adding buttons from array to the form
Controls.Add(tiles25[count]);
tiles25[count].Click += Tiles25_Click;
count++;
x = x + 24;
}
x = 35;
y = y + 24;
}
lblSize.Text = "5 x 5";
currentGrid = Grids.grid5x5;
}
private void Tiles25_Click(object sender, EventArgs e)
{
var bt = sender as Button;
MessageBox.Show("X = " + bt.Location.X + "; Y = " + bt.Location.Y);
}
You need to set up an event handler for when the button is clicked. Right now, all you're doing is creating the buttons and adding them to the list of controls at a given position. Now, all you have to add is the event handler for the click event!
//...
// Adding button to the array
tiles25[count] = new Button()
{
Size = new Size(24, 24),
Location = new Point(x, y),
};
tiles25[count] += new EventHandler(this.Tile_Click);
//...
void Tile_Click(Object sender, EventArgs e)
{
Button clickedButton = (Button)sender;
//...
}
Then inside of the Tile_Click() event handler, you can use whatever code necessary to get the position with the clickedButton object.
If I'm not wrong VoidWalker, you are trying to get the position(index) of the item in the source array and not the actual position of the button on screen. If the former case is true read on, for the latter we have some good answers above.
What you need to do is to mark each button with an identifier that would be used to infer the position. A simple yet damn efficient approach.
At the time of creating the button:
// Adding button to the array
tiles25[count] = new Button()
{
Size = new Size(24, 24),
Location = new Point(x, y)
};
// Add the current index to the name field of the Button
tiles25[count].Name = "Grid5-Btn" + count.ToString();
// Adding buttons from array to the form
Controls.Add(tiles25[count]);
Then on button click you can simply do
void Tile_Click(Object sender, EventArgs e)
{
Button clickedButton = (Button)sender;
var index = int(clickedButton.Name.Split("Grid5-Btn")[0]);
//...
}
This way you can add multiple pieces of informatio such as the hierarchy of grids on the page. You can exactly pinpoint which element to access without running any loops, which would be the case with Array.IndexOf

How to Reset scrollbar to top of window

I am working on a Winform app using .net 4.5.
In my project, I have a window that contains only a button.
WHen the window is displayed, I add lots of controls dynamically to the point that a scrollbar is needed.
Once the controls are added, I move the single button to the bottom of the controls in the window.
This step of moving the button to the bottom of the controls makes the window scroll to the bottom. I have tested this by not moving the button to the bottom of the form, and the scroll stays at the top.
I have tried "this.VerticalScroll.Value = 0;" both before and after setting the position of the button.
Here is the code so you can get a clearer idea of what I am attempting to do:
public SignoffSurvey(int task_id)
{
InitializeComponent();
this.task_id = task_id;
int form_top = 10;
int question_num = 0;
XmlDocument doc = new XmlDocument();
doc.Load(DBHandler.getSetting("files_directory") + "\\" + "questionaire.xml");
foreach (XmlNode node in doc.SelectNodes("/Questions/Question"))
{
question_num++;
string type = node.Attributes["type"].Value;
int top = 0;
Panel pnl = new Panel();
pnl.AutoSize = true;
pnl.Top = form_top;
pnl.Left = 10;
Label text_lbl = new Label();
text_lbl.Top = top;
text_lbl.AutoSize = true;
text_lbl.Text = node["text"].InnerText;
pnl.Controls.Add(text_lbl);
top += text_lbl.Height + 5;
if (type == "mc" || type == "mct")
{
XmlNode choices = node["choices"];
Boolean fc = false;
foreach (XmlNode choice in choices.ChildNodes)
{
RadioButton rb = new RadioButton();
rb.AutoSize = true;
rb.Text = choice.InnerText;
rb.Top = top;
rb.Left = 10;
top += rb.Height + 5;
pnl.Controls.Add(rb);
if (!fc) // check first item.
{
fc = true;
rb.Checked = true;
}
}
}
if (type == "mct" || type == "txt")
{
TextBox tb = new TextBox();
tb.Multiline = true;
tb.Width = 500;
tb.Height = 250;
tb.Top = top;
tb.Left = 10;
pnl.Controls.Add(tb);
top += tb.Height + 5;
}
pnl.Height = top;
this.Controls.Add(pnl);
form_top += pnl.Height + 10;
}
this.VerticalScroll.Value = 0;
this.save_btn.Top = form_top;
}
HOw can I force the window vertical scroll to the top regardless of where this 1 button is moved to?
Okie. For anyone with a similar issue, here is the reason for the problem and how to overcome it.
The problem appears to be that the single button is 'selected' by default on the window. So when the window launches, it scrolls to the position of the button.
I added this:
this.Controls[1].Select();
after adding all my controls.
You have to use [1] because the button already on the form is [0].

How Can I Add multipe buttons on c# dynamically using point class?

Hello I try to add multiple Buttons on a panel on form and next to each other but instead it put them above each other.
I am using the following function.
the Code:
private void CreatBtn()
{
Point[] p = new Point[6];
string log = "";
Form2 frm2 = new Form2();
Button[] btn = new Button[6];
for (int i = 0; i < btn.GetLength(0); i++)
{
btn[i] = new Button();
btn[i].Height = 65;
btn[i].Width = 80;
p[i] = new Point();
p[i].X = i * 83;
p[i].Y =0;
log +=p.ToString() +"\n";
btn[i].PointToClient(p[i]);
btn[i].Show();
}
panel1.Controls.AddRange(btn);
}
Add a Left value to your buttons
btn[i] = new Button();
btn[i].Height = 65;
btn[i].Width = 80;
btn[i].Left = i * 83; //Now they'll be next to each other.
You may also consider using the FlowLayoutPanel.
Use flowLayoutPanel in the panel of it'll but the next to each other until the button reach the end of it, then it will make an new raw
Point[] p = new Point[6];
string log = "";
Button[] btn = new Button[6];
for (int i = 0; i < btn.GetLength(0); i++)
{
btn[i] = new Button();
btn[i].Height = 65;
btn[i].Width = 80;
p[i] = new Point();
p[i].X = i * 83;
p[i].Y = 0;
log += p.ToString() + "\n";
btn[i].PointToClient(p[i]);
btn[i].Show();
}
FlowLayoutPanel pan = new FlowLayoutPanel();
pan.Width=500;//width of all buttons
pan.Height = 100;
pan.Controls.AddRange(btn);
panel1.Controls.Add(pan);

why doesnt my panel show all my buttons in my c# application?

my panel in my windows form application doesn't include all the buttons i asked it to. It shows only 1 button, Here is the code
private void AddAlphaButtons()
{
char alphaStart = Char.Parse("A");
char alphaEnd = Char.Parse("Z");
for (char i = alphaStart; i <= alphaEnd; i++)
{
string anchorLetter = i.ToString();
Button Buttonx = new Button();
Buttonx.Name = "button " + anchorLetter;
Buttonx.Text = anchorLetter;
Buttonx.BackColor = Color.DarkSlateBlue;
Buttonx.ForeColor = Color.GreenYellow;
Buttonx.Width = 30;
Buttonx.Height = 30;
this.panelButtons.Controls.Add(Buttonx);
//Buttonx.Click += new System.EventHandler(this.MyButton_Click);
}
}
Aren't they all going to be on the same position?
Try setting Buttonx.Location = new Point(100, 200);
(but with different points for different buttons)
You could use a FlowLayoutPanel, which would take care of the layout for you, or you need to track the locations yourself, or which could look something like this:
private void AddAlphaButtons()
{
char alphaStart = Char.Parse("A");
char alphaEnd = Char.Parse("Z");
int x = 0; // used for location info
int y = 0; // used for location info
for (char i = alphaStart; i <= alphaEnd; i++)
{
string anchorLetter = i.ToString();
Button Buttonx = new Button();
Buttonx.Name = "button " + anchorLetter;
Buttonx.Text = anchorLetter;
Buttonx.BackColor = Color.DarkSlateBlue;
Buttonx.ForeColor = Color.GreenYellow;
Buttonx.Width = 30;
Buttonx.Height = 30;
// set button location
Buttonx.Location = new Point(x, y);
x+=30;
if(x > panel1.Width - 30)
{
x = 30;
y+=30;
}
this.panelButtons.Controls.Add(Buttonx);
//Buttonx.Click += new System.EventHandler(this.MyButton_Click);
}
}

Categories

Resources