Change all buttons on a form

I came very close to finding a solution to this problem; just one minor detail is missing at this moment.

What I'm trying to do:
I want to change the cursor style for each button in my form (Form1) through code. I know how to look for all the controls in my form using foreach, but I'm not sure how to pass this control as a parameter through the routine I wrote. I will show an example of what I am doing below.

private void Form1_Load(object sender, EventArgs e) { foreach (Button b in this.Controls) { ChangeCursor(b); // Here is where I'm trying to pass the button as a parameter. Clearly this is not acceptable. } } private void ChangeCursor(System.Windows.Forms.Button Btn) { Btn.Cursor = Cursors.Hand; } 

Maybe someone has a clue for me?

Thank you very much

Evan

+4
source share
6 answers

The only thing I see is that if you have nested controls, this.Controls does not pick them up. you can try this

 public IEnumerable<Control> GetSelfAndChildrenRecursive(Control parent) { List<Control> controls = new List<Control>(); foreach(Control child in parent.Controls) { controls.AddRange(GetSelfAndChildrenRecursive(child)); } controls.Add(parent); return controls; } 

and call

 GetSelfAndChildrenRecursive(this).OfType<Button>.ToList() .ForEach( b => b.Cursor = Cursors.Hand); 
+7
source

Change

 foreach (Button b in this.Controls) { ChangeCursor(b); // Here is where I'm trying to pass the button as a parameter. // Clearly this is not acceptable. } 

to

 foreach (Control c in this.Controls) { if (c is Button) { ChangeCursor((Button)c); } } 

Not every form control is a button.

Edit: You should also look for nested controls. See Answer Bala R.

+7
source

Same principle as Bala R's answer, but the way I do it ...

 using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace AppName { public static class ControlExtensions { public static IEnumerable<Control> GetAllCtls(this Control control, Type type) { var controls = control.Controls.Cast<Control>(); return controls.SelectMany(ctrl => GetAllCtls(ctrl, type)) .Concat(controls) .Where(c => c.GetType() == type); } } } 

Then use it like this:

 foreach (Control ctl in this.GetAllCtls(typeof(Button))) { MessageBox.Show("Found a button on the form called '" + ctl.Text + "'"); } 
+2
source

It looks right to me; is there a problem that i don't see?

EDIT: Ahh yes - if you have controls other than a button, the collection will fail.

You only want to pass controls that are buttons, so you need to add an IF statement.

+1
source

If any of your controls are not inherited from the button, I think your foreach will throw an exception.

try something like this:

 foreach (Control b in this.Controls) { if (b is Button) ChangeCursor((Button)b); } 
+1
source

You can also use for cleaner syntax:

 foreach (Control c in this.Controls) { if (c is Button) { ChangeCursor(c as Button); } } 
+1
source

All Articles