Click here to Skip to main content
15,878,809 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello Everyone!
I have yet another question,
How to i subscribe to an event for every control that exist in my form?
Here is what i have so far:

C#
foreach (Control ctrl in this.Controls)
{
    ctrl.MouseEnter += new System.EventHandler(this.Form1_MouseEnter);
    ctrl.MouseLeave += new System.EventHandler(this.Form1_MouseLeave);
}


Marcin Kozub gave me a this solution C# How To Tell If A WinForm Has Focus Or Not?[^]
where he subscribed to the events "MouseEnter" and "MouseLeave" for the main form only
now what i want to do is to use a for each loop to suscribe to those 2 events for every control that i have in my form.
sorry Marcin and or everyone if i am being picky.
thanks for everyone's help again!
who knows i just might do an article about this app i am developing (it mimics what a star trek computer, but just not the firing phasers or torpedoes part)

--UPDATE--
Marcin Kozub solved part of the reason i had this problem and now i have encountered the same problem just in a different form.
i was trying to loop through all the controls in the form and set there visibility to either true or false based on a variable that i set but then i encountered the problem where i it would set ALL the controls to either visible or not nut just the keyboard buttons i wanted(i made a onscreen keyboard out of button controls).
here is what i am using currently to do this:

C#
foreach (Button ctrl in this.Controls)
{
    ctrl.Visible = true;
}

but when i do this VS gives me an InvalidCastException error saying:
Unable to cast object of type 'System.Windows.Forms.ListBox' to type 'System.Windows.Forms.Button'.
this is because i have a ListBox and i should have seen this comming but the types won't work with each other(duh! i said to my self!)
so how do i solve this?
Posted
Updated 16-Dec-14 10:49am
v3
Comments
Kornfeld Eliyahu Peter 16-Dec-14 15:19pm    
Your question is not clear...
MasterCodeon 16-Dec-14 15:31pm    
i want to know how to iterate through all controls of a form, and for each control in the form, subscribe to an event linked to the (whatever the name control is that i am currently accessing in a foreach loop) on the form.
Kornfeld Eliyahu Peter 16-Dec-14 15:35pm    
So? You already have a loop for the first level of controls, if you want to go deeper than create some kind of recursion...That's what you are looking for?
(Also consider that not all control necessarily have all the events you want)
MasterCodeon 16-Dec-14 15:41pm    
no not really i don't have any child control(unless you count buttons on a context menu strip) but the only events i want to subscribe to are the "MouseEnter" and the "MouseLeave" events, so i am pretty sure all of my buttons, list boxes, text boxes and labels will have those events.
And my foreach loop that i have does not work.
Kornfeld Eliyahu Peter 16-Dec-14 15:42pm    
Doesn't work in what way?

You would need to create a recursive method traversing all controls of some parent control; for example:
C#
using System;
using System.Windows.Forms;

//...

static void SubcribeToMouseEnterLeaveEvents(Control parent, EventHandler enterHandler, EventHandler leaveHandler) {
    foreach (Control child in parent.Controls)
        SubcribeToMouseEnterLeaveEvents(child, enterHandler, leaveHandler);
    parent.MouseEnter += enterHandler;
    parent.MouseLeave += leaveHandler;
}

Then, if you really need to subscribe for all controls on the form, call it starting from your form instance (remember that Form is Control); for example:
C#
SubcribeToMouseEnterLeaveEvents(myFormInstance, // could be "this",
                                                // if called in you form class
    (sender, eventArgs) => {
        // something you want to do on enter
    }, (sender, eventArgs) => {
        // something you want to do on leave
    });

That's it. For the events using other EventArgs types (derived from System.EventArgs), you would need to use generic System.EventHandler<>.

—SA
 
Share this answer
 
v2
Comments
MasterCodeon 16-Dec-14 16:05pm    
I get the first part but when i try to use the second code snippet VS gives me 12 errors
could you explain a little more i don't get it
sorry i am kind of a newbie
Sergey Alexandrovich Kryukov 16-Dec-14 16:21pm    
Of course I tested everything before posting. Compilation errors? What is your C# version? If it's too low, I'll tell you the other way on the second fragment.
But what could be a problem for you? If you know how to subscribe to one event on one control instance, everything else should not be a problem.
—SA
MasterCodeon 16-Dec-14 16:27pm    
uh i don't know how to find what version of C# i am using but i know i am using Visual Studio 2010 and the .NET Framework 4.5(but i know the .NET version has nothing to do with C# version)
and is the second snippet supposed to be a void, is it supposed to be public private what?
sorry for being such a newbie when it comes to this
i have worked with python for 2 years and a couple of years before that my dad started to teach me C# and just recently i picked up C# again(but i am doing pretty good at it so far, or at least i know the basics.)
BillWoodruff 16-Dec-14 22:11pm    
Sergey, the code will not work for the simple reason that the recursive call is incorrect:

SubcribeToEvent(child, enterHandler, leaveHandler);

should read:

SubcribeToMouseEnterLeaveEvents(child, enterHandler, leaveHandler);

I suspect the same demon that messes with my code messed with yours :)
Sergey Alexandrovich Kryukov 17-Dec-14 0:05am    
Ah, thank you very much, I just renamed the method at the last moment. Fixing...
—SA
If you use the stack-based recursive technique I demonstrate here [^], you can easily get all the Buttons
C#
foreach(Control theControl in (SpecialMethods.GetAllControls(this)).OfType<Button>().ToList())
{
    // do something with/to/using each Button
}
There's another QA answer I posted yesterday (Dec. 16, 2014), demonstrating using stack based recursion: [^].

It's important to know when you do, or do not, want recursion ! If all your Buttons you want to add EventHandlers to are in the ControlCollection of one container (Form, Panel, etc.), then you do not want recursion: you can build your List<Button> by simply:
C#
List<Button> ButtonList = ButtonContainer.Controls.OfType<Button>().ToList();
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 17-Dec-14 0:12am    
Not that OP explicitly asked about one particular control type, but this answer gives the idea; a 5.
—SA
Maciej Los 17-Dec-14 2:06am    
+5
MasterCodeon 17-Dec-14 10:03am    
wow thats a way better idea than mine thank you so much!
BillWoodruff 17-Dec-14 10:28am    
Glad you found this useful; keep in mind that using TypeOf<> requires a reference to System.Linq
Marcin Kozub 17-Dec-14 10:49am    
+5. Nice idea using Stack instead of typical recurrency :)
I solved my updated problem my self!
here is the code i sued to solve the UPDATED problem NOT the first problem:

first i declare a public List like this:
C#
public List<string> ButtonList = new List<string>();
</string></string>

next i add all the buttons i want to manipulate:
C#
ButtonList.Add(V.Name);
ButtonList.Add(W.Name);
ButtonList.Add(X.Name);
ButtonList.Add(Y.Name);
ButtonList.Add(Z.Name);
ButtonList.Add(Sqig.Name);
ButtonList.Add(Btn1.Name);
ButtonList.Add(Btn2.Name);
ButtonList.Add(Btn3.Name);
//ect.. ect..

and now when i want to make the buttons disappear or reappear i just illiterate through the list like this:
C#
foreach (string ctrl in ButtonList)
{
    this.Controls[ctrl].Visible = false;
}


--UPDATE--
this update is thanks to BillWoodruff and his solution.
so instead of adding all the controls manualy i just get all the controls of the type "Button and add those to the list like this:
C#
ButtonList = this.Controls.OfType<Button>().ToList();


i had to change the ButtonList declaration line from:
C#
public List<string> ButtonList = new List<string>();

to:
C#
public List<Button> ButtonList = new List<Button>();

i just changed the List type from string to Button
but i didn't want 5 of the function buttons i just wanted the Onscreen keyboard buttons to be added to the list so i just removed them like this:
C#
ButtonList.Remove(LockThisComputer);
//ect.. ect..

and then when i want to change something with the buttons i just illiterate through the list like this:
C#
foreach (Button ctrl in ButtonList)
{
    //Do whatever you want to the current button by using the variable "ctrl" and           whatever the operation you wanted to do with the button
    //here is an example:
    ctrl.Visible = Boolean.Parse(OskEnabled);
    //OskEnabled is a global string variable that i load and set at runtime but here it is Parsed by the Boolean.Parse method.

}

in conclusion both of the solutions work its just that the updated one is sooo much easier.
thank you all very much for helping me with my coding problems,
MasterCodeon
 
Share this answer
 
v2
Comments
Philippe Mori 16-Dec-14 20:56pm    
If you do a list then why not make a list of buttons (or controls) directly. Simpler and more efficient and also easier to debug as you can directly inspect the list.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900