user725913
user725913

Reputation:

Change all buttons on a form

I have come very close to finding a solution to this one; just missing one minor detail at this point.

What I am trying to do:
I want to change the cursor style of every button on my Form (Form1) through code. I know how to search through all controls on my form using foreach, but I'm not sure how to pass this control as a parameter through the routine that 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;
}

Might anyone have a tip for me?

Thank you very much

Evan

Upvotes: 4

Views: 18390

Answers (6)

Arvo Bowen
Arvo Bowen

Reputation: 4955

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

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 + "'");
}

Upvotes: 2

Liviu Trifoi
Liviu Trifoi

Reputation: 3030

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 control on a form is a button.

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

Upvotes: 7

Morgan Herlocker
Morgan Herlocker

Reputation: 1483

You could also use for a bit cleaner syntax:

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

Upvotes: 1

Bala R
Bala R

Reputation: 109027

The only thing I see is that if you have nested controls, this.Controls will not pick those 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);

Upvotes: 7

Russell Troywest
Russell Troywest

Reputation: 8776

If any of your controls fail to inherit from 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);  
}    

Upvotes: 1

Rob P.
Rob P.

Reputation: 15091

That looks correct to me; is there a problem I'm not seeing?

EDIT: Ahh yes - if you have non-button controls in the collection, the cast will fail.

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

Upvotes: 1

Related Questions