Reputation:
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
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
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
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
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
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
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