Set Properties via runtime for Multiple Controls - c#

I have a form that contains about 25 Buttons. I want to set the same property for the Multiple buttons based on user input. The properties i want to change are,
Button text
Button Fore Color
Button Back Color
Button Size
I have been able to do this using code but the Code is long. I want to know if there is a way to loop to change all of them.
This is what i used
button1.Text = btntext;
button1.ForeColor = btnforecolor;
button1.BackColor = btnbackcolor;
button1.Size = new Size(btnwidth, btnheight);
I had to do this like this for the 25 button, i want to know if there is any better way to do this with less code??..
Any suggestion will be appreciated.

Two options here:
1) Create a list of buttons and loop:
for (int i = 0; i < 25; i++){
Button btn = new Button();
btn.Text = ...
btn.Location = new Point(10 + (i%5)*100, (i/5)*30);
btn.Click += new EventHandler(btn_Click); // TODO: Implement btn_Click event
this.Controls.Add(btn);
}
2) Loop through your existing controls:
foreach (Control c in this.Controls) {
Button btn = c as Button;
if (btn == null) continue;
btn.Text = ...
}

If you can't iterate through all of the buttons on a form but need a specific list of buttons I use this code.
List<Button> ListOfButtons = new List<Button>
{
this.Button1,
this.Button2,
}
foreach (Button myButton in ListOfButtons)
{
//Do your assigments to myButton
}

Related

Change properties of programmatically created buttons

I create buttons in my application by:
List<Button> btnslist = new List<Button>();
for (int i = 0; i < nbrofbtns; i++)
{
Button newButton = new Button();
btnslist.Add(newButton);
this.Controls.Add(newButton);
newButton.Width = btnsidelength;
newButton.Height = btnsidelength;
newButton.Top = btnsidelength
* Convert.ToInt32(Math.Floor(Convert.ToDouble(i / Form2.puzzlesize)));
newButton.Left = btnsidelength
* Convert.ToInt32(
Math.Floor(Convert.ToDouble(i))
- Math.Floor((Convert.ToDouble(i))
/ (Form2.puzzlesize)) * (Form2.puzzlesize));
newButton.BackgroundImage = Lights_out_.Properties.Resources.LightsOutBlack;
newButton.Tag = (i+1).ToString();
newButton.Click += new EventHandler(Any_Button_Click);
Then I have a method for when any of the buttons are clicked.
void Any_Button_Click(object sender, EventArgs e)
{
//the variable b has all the insformation that the single button had itself.
Button b = (Button)sender;
if (b.BackgroundImage == Lights_out_.Properties.Resources.LightsOutBlack)
{
MessageBox.Show(b.Tag.ToString());
MessageBox.Show(btnslist[Convert.ToInt32(b.Tag)].BackgroundImage.ToString());
btnslist[Convert.ToInt32(b.Tag)].BackgroundImage =
Lights_out_.Properties.Resources.LightsOutWhite;
MessageBox.Show(btnslist[Convert.ToInt32(b.Tag)].BackgroundImage.ToString());
}
else
{
MessageBox.Show("b.backgroundimage != lightsoutblack. Backgroundimage = "
+ b.BackgroundImage.ToString());
}
}
How do I change the data in the actual button (then said button is clicked)? I want specificly to change the backgroundimage. How could I do this?? (I also need to change the backgroundimage of some other buttons created by the code.)
The sender object is the button:
Button b = (Button)sender;
... so you should be able to change properties on it directly:
b.WhateverPropsToChange = yourSetting;
PS: I don't think this is necessary, but if the button is not updated directly, you might try to using b.Refresh() to let it know something has changed.
You're handling Click event of every button you've created - and sender in Any_Button_Click is actually the button was clicked.
So just change b.BackgroundImage to whatever you need.

C# - Use too many buttons as 1 variable

I have a fairly simple question. I want to change the background color of 15 buttons,
but is is very cumbersome to write
button1.backgroundColor = Color.black
button2.backgroundColor = Color.black
.
.
.
How i can assign the color to all these buttons at once?
Like:
something allButtons = { button1.backgroundColor, button2.backgroundcolor .... }
I know how to do this in obj-c:
for (int i = 1; i < 16; i++)
{
UIButton *button = (UIButton *)[tag:i];
button.backgroundColor = [UIColor Color.black];
}
but how to accomplish this in C#?
You might be able to iterate through all the controls on the form, looking for buttons.
foreach (Control c in this.Controls)
{
if (c.GetType() == typeof(Button))
{
c.BackColor = Color.Black;
}
}
You put your buttons in an button array
Button[] buttons = new Button[] {button1, button2, .....};
Or in a List<Button>
List<Button> buttons = new List<Button>() { button1, button2, ....);
Next you loop over the button array or the List in the same way
foreach(Button btn in buttons)
btn.BackColor = Color.Black;
Another way to change this property is looping using the Forms.Controls container. But this will work only if the buttons are all contained in the Form.Controls collection.
foreach (Control btn in this.Controls.OfType<Button>())
{
btn.BackColor = Color.Black;
}
To fix the problem of buttons contained in inner ControlCollection you should use a recursive function that loops on every control container and reach buttons eventually inside that container
public void SetBackground(Control.ControlCollection coll)
{
foreach(Control ctr in coll)
{
if(ctr.Controls.Count > 0)
SetBackground(ctr.Controls);
else
{
Button btn = ctr as Button;
if(btn != null) btn.BackColor = Color.Black;
}
}
}
and call it from the toplevel collection
SetBackground(this.Controls);
It is a lot more complicated, so I prefer to use an array to explicitily declare the buttons that need to be changed.

How to change properties of a Control that is in List<UIControl> without using Loop?

I have the following code where a click event will dynamically create additional Canvas to the WrapPanel, and each Canvas contains a TextBox and a Button. Once the Button on one Canvas is click, TextBox.Text and Button.Content change from "Foo" to "Jesus".
The below code works, but it's not ideal. Because each property Change ("Foo" to "Jesus), I have to run a loop. I have to run two loops just to change the text on the TextBox and Button. Is there a direct way to change the Properties other then a Loop? My actually application contains 30+ controls in a Canvas, I don't want to run 30+ loops each time just to change some text.
List<Canvas> cvList = new List<Canvas>();
List<TextBox> tbList = new List<TextBox>();
List<Button> FooList = new List<Button>();
WrapPanel wp = new WrapPanel();
private void createbtn1_Click(object sender, RoutedEventArgs e)
{
Canvas cv = new Canvas();
StackPanel sp = new StackPanel();
TextBox tb = new TextBox();
Button Foo = new Button();
sp.Orientation = Orientation.Vertical;
sp.Children.Add(tb);
sp.Children.Add(Foo);
cv.Children.Add(sp);
wp.Children.Add(cv);
cvList.Add(cv);
tbList.Add(tb);
FooList.Add(Foo);
cv.Width = 100;
cv.Height = 100;
tb.Text = "#" + (cvList.IndexOf(cv)+1);
tb.Width = 50;
tb.Height = 30;
Foo.Content = "Foo";
Foo.Click += destroy_Click;
}
private void Foo_Click(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
var bIndex = FooList.IndexOf(b);
foreach (TextBox t in tbList)
{
if (tbList.IndexOf(t) == bIndex)
{
t.Text = "Jesus";
}
}
foreach (Button f in FooList)
{
if (FooList.IndexOf(t) == bIndex)
{
t.Content = "Jesus";
}
}
}
Just access the text boxes by index and set the content of the button directly:
if(bIndex < tbList.Count && bIndex != -1)
tbList[bIndex].Text = "Jesus";
if(b != null && bIndex != -1)
b.Content = "Jesus";
why can't you just get the item at the index and set that items text:
tbList[bindex].Text="Jesus";
As for setting the buttons content, you already have the button from the click event, so just use that:
b.Content = "Jesus";
You current code just loops through each item in the list and gets the index of the item and sees if it is the index you want. Accessing by the indexer of the list directly will give you what you want.
You will probably want to do some error checking, but that is not currently done in your existing code either.
Some info on using indexers from MSDN

Create button during runtime in C#.net?

I know how to create button during runtime.
Button button1 = new Button();
button1.Location = new Point(20,10);
button1.Text = "Click Me";
// adding to groupBox1
groupBox1.Controls.Add(button1);
But the problem is i want to add multiple buttons like this..
for(int i = 1; i < 30; i++) {
Button button[i] = new Button();
// Button customization here...
...
groupBox1.Controls.Add(button[i]);
}
The code above is false code. How can I make this happen true in C#.net? i want to create multiple buttons with button name, button1, button2, button3, button4, .... button30;
You can't declare extra variables at execution time in C# - but you really don't want to anyway, as you wouldn't be able to access them dynamically afterwards. Just create an array:
// buttons would be declared as Button[] as a member variable
buttons = new Button[30];
for(int i = 0; i < buttons.Length; i++) {
buttons[i] = new Button();
// Button customization here...
...
groupBox1.Controls.Add(buttons[i]);
}
Alternatively, use a List<Button>, which will certainly be more convenient if you don't know how many buttons you need beforehand. (See the obligatory "arrays considered somewhat harmful" blog post.)
Of course, if you don't actually need to get at the buttons later, don't bother assigning them to anything visible outside the loop:
for(int i = 0; i < 30; i++) {
Button button = new Button();
// Button customization here...
...
groupBox1.Controls.Add(button);
}
You need to think about what information you need access to when... and how you want to access it. If you logically have a collection of buttons, you should use a collection type variable (like a list or an array).
Frankly I think it's one of the curses of the VS designers that you end up with horrible names such as "groupBox1" which carry no information beyond what's already in the type declaration, and encourage developers to think of collections of controls via individually-named variables. That's just me being grumpy though :)
Try this
for(int i = 1; i < 30; i++) {
Button button = new Button();
// Button customization here...
button.Name = "Button" + i.ToString();
groupBox1.Controls.Add(button);
}
You seem like you're almost on the right track:
// in form class
Button[] m_newButtons = new Button[30];
// in your trigger function
for(int i = 0; i < 30; ++i)
{
m_newButtons[i] = new Button();
// ...
groupBox1.Controls.Add(m_newButtons[i]);
}
If you try and do this more than once you may have to remove the old buttons from the control before adding the new ones.
buttons = new Button[30];
for(int i = 0; i < buttons.Length; i++) {
buttons[i] = new Button();
groupBox1.Controls.Add(buttons[i]);
}
this code will work but button will be added one over other so set location also
buttons = new Button[30];
for(int i = 0; i < buttons.Length; i++)
{
buttons[i] = new Button();
Point p=new Point(xvalue,yvalue);
buttons[i].Location = p;
groupBox1.Controls.Add(buttons[i]);
}
one thing you want to remember increment the x or y position by which you want to display it
Try this one out, I have just learned it myself:
public partial class Form1 : Form
{
Button[] btn = new Button[12];// <--------<<<Button Array
public Form1()
{
InitializeComponent();
}
private void Form1_Load (object sender, EventArgs e)
{
for (int i = 0; i < 12; i++)
{
btn[i] = new Button ( );
this.flowLayoutPanel1.Controls.Add(btn[i]);
}
}
// double click on the flow layoutPannel initiates this code
private void flowLayoutPanel1_Paint(object sender, PaintEventArgs e)
{
}
}

10x10 grid of 100 buttons: hiding a button on click (C#)

I have a 10x10 grid of 100 buttons, I want to hide a button when it is clicked.
Is there a way to apply this to all buttons?? i.e. When any of the button is clicked then that button is hidden. I use a table layout to arrange the 100 buttons in C#.
also im adding it to table layout so kindly tell me how to add these buttons to that 10x10 table grid..here how will the button objects be named and how to add individual events all performing the action to itself(that is hide itself when clicked)
Create 100 buttons
foreach (int i in Enumerable.Range(0, 10))
{
foreach (int j in Enumerable.Range(0, 10))
{
Button b = new Button();
b.Size = new System.Drawing.Size(20, 20);
b.Location = new Point(i * 20, j * 20);
b.Click += new EventHandler(anyButton_Click); // <-- all wired to the same handler
this.Controls.Add(b);
}
}
and connect them all to the same event handler
void anyButton_Click(object sender, EventArgs e)
{
var button = (sender as Button);
if (button != null)
{
button.Visible = false;
}
}
in the eventhandler you cast sender to Button and that is the specific button that was pressed.
Since you are using tablelayoutpanel, you don't need to calculate positions for the buttons, the control is doing it for you. You can also set the buttons dock property to be fill, so you don't need to setup size of the buttons. All you'll have to do is to setup the properties of the tableLayoutPanle
So..
Button b;
foreach (int i in Enumerable.Range(0, 100))
{
b = new Button();
//b.Size = new System.Drawing.Size(20, 20);
b.Dock = DockStyle.Fill
b.Click += new EventHandler(anyButton_Click); // <-- all wired to the same handler
tableLayoutPanel.Controls.Add(b);
}

Categories