C#如何为表单中的每个控件订阅一个事件? [英] C# How To Subscribe To An Event For Each Control In A Form?

查看:98
本文介绍了C#如何为表单中的每个控件订阅一个事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好!

我还有另外一个问题,

如何订阅我的表单中存在的每个控件的事件?

以下是我到目前为止:



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:

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





Marcin Kozub给了我一个解决方案 C#如何判断WinForm是否有焦点? [ ^ ]

他只为主表单订阅了MouseEnter和MouseLeave事件

现在我要做的是为每个循环使用a为我在我的表格中控制的每个控件都要接受这两个事件。

对不起Marcin和大家,如果我挑剔的话。

再次感谢大家的帮助!

谁知道我可能会做一篇关于我正在开发的这个应用程序的文章(它模仿一个星际迷航电脑,但不是点火器或鱼雷部分)



--UPDATE--

Marcin Kozub解决了我遇到这个问题的部分原因,现在我有了鼓励只是以不同的形式改变了同样的问题。

i试图循环遍历表单中的所有控件,并根据我设置的变量将可见性设置为true或false,但后来我遇到了问题在哪里我会将所有控件设置为可见或不是我刚想要的键盘按钮(我用按钮控件制作屏幕键盘)。

这里是我目前正在使用的这个:





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:

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



但是当我这样做时VS给我一个InvalidCastException错误说:

无法转换'System'类型的对象。 Windows.Forms.ListBox'键入'System.Windows.Forms.Button'。

这是因为我有一个ListBox,我应该已经看到了这个混合,但这些类型不会互相帮助(呃!我对自己说了!)

所以我该如何解决这个问题?


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?

推荐答案

你需要创建一个递归方法遍历某些父控件的所有控件;例如:

You would need to create a recursive method traversing all controls of some parent control; for example:
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;
}



然后,如果您确实需要订阅表单上的所有控件,请从表单实例开始调用它(请记住表单 Control );例如:


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:

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
    });



就是这样。对于使用其他 EventArgs 类型的事件(派生自 System.EventArgs ),您需要使用泛型 System.EventHandler<>



-SA


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

—SA


如果您使用基于堆栈的递归技术,我在此处演示[ ^ ],您可以轻松获取所有按钮
If you use the stack-based recursive technique I demonstrate here [^], you can easily get all the Buttons
foreach(Control theControl in (SpecialMethods.GetAllControls(this)).OfType<Button>().ToList())
{
    // do something with/to/using each Button
}

我昨天(2014年12月16日)发布了另一个QA答案,演示了使用基于堆栈的递归:[ ^ ]。



重要的是要知道你什么时候做,或者不想要递归!如果你想要添加EventHandlers的所有按钮都在一个容器的ControlCollection中(Form,Panel等),那么你想要递归:你可以构建你的List< 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:

List<Button> ButtonList = ButtonContainer.Controls.OfType<Button>().ToList();


我解决了我自己更新的问题!

这里是我起诉解决UPDATED问题的代码而不是第一个问题:



首先我声明一个这样的公共列表:

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:
public List<string> ButtonList = new List<string>();
</string></string>



接下来我添加了我想要操作的所有按钮:


next i add all the buttons i want to manipulate:

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:

foreach (string ctrl in ButtonList)
{
    this.Controls[ctrl].Visible = false;
}





--UPDATE--

此更新归功于BillWoodruff及其解决方案。

所以不要手动添加所有控件而只是获取按钮类型的所有控件并将其添加到列表中,如下所示:



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

ButtonList = this.Controls.OfType<Button>().ToList();





i必须更改ButtonList声明行:



i had to change the ButtonList declaration line from:

public List<string> ButtonList = new List<string>();



to:


to:

public List<Button> ButtonList = new List<Button>();



i刚刚将List类型从字符串更改为Button

但我不想要5个功能按钮我只想要屏幕键盘按钮被添加到列表中,所以我就像这样删除它们:


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:

ButtonList.Remove(LockThisComputer);
//ect.. ect..



然后当我想用按钮更改某些东西时,我只是通过列表文盲:


and then when i want to change something with the buttons i just illiterate through the list like this:

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.

}



总结两个解决方案的工作原理只是更新的一个更容易。

非常感谢你帮我解决我的编码问题,

MasterCodeon


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


这篇关于C#如何为表单中的每个控件订阅一个事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆