C# 事件以启用应用按钮

C# 事件以启用应用按钮,c#,winforms,events,button,apply,C#,Winforms,Events,Button,Apply,我的标准winform上的应用按钮在加载时被禁用,如果任何其他控件的状态发生更改(复选框、RadioBox、文本框等),我希望启用它 因此,我可以浏览每个控件的事件,并在那里启用按钮,但我想知道是否有更简单的方法,比如全局事件 编辑 澄清一下:我正在寻找一种方法,在这种方法中,我不必对每个控件都做任何事情。这样我可以在以后添加更多控件,而不必关心它们 根据您的编辑,我已经修改了我的答案,以包含您想要的功能 首先,您需要一个通用事件处理程序,它应该如下所示: void MyHandler(obje

我的标准winform上的应用按钮在加载时被禁用,如果任何其他控件的状态发生更改(复选框、RadioBox、文本框等),我希望启用它

因此,我可以浏览每个控件的事件,并在那里启用按钮,但我想知道是否有更简单的方法,比如全局事件

编辑
澄清一下:我正在寻找一种方法,在这种方法中,我不必对每个控件都做任何事情。这样我可以在以后添加更多控件,而不必关心它们

根据您的编辑,我已经修改了我的答案,以包含您想要的功能

首先,您需要一个通用事件处理程序,它应该如下所示:

void MyHandler(object obj, EventArgs e)
{
    button1.Enabled = true;
}
public Form1()
{
    InitializeComponent();
    AddEvents(this.Controls);
}
其中button1是您希望启用的按钮

然后,您将需要一个递归方法,不仅可以迭代
表单.Controls
,还可以迭代其中包含的任何容器类型控件。我已经介绍了一些常见容器控件以及一些基本数据输入控件的处理:

void AddEvents(System.Windows.Forms.Control.ControlCollection Controls)
{
    foreach (Control c in Controls)
    {
        if (c is GroupBox)
        {
            AddEvents(((GroupBox)c).Controls);
        }
        else if (c is Panel)
        {
            AddEvents(((Panel)c).Controls);
        }
        //Expand this series of if...else... to include any 
        //other type of container control
        else if (c is TextBox)
        {
            ((TextBox)c).TextChanged += new EventHandler(MyHandler);
        }
        else if (c is RichTextBox)
        {
            ((RichTextBox)c).TextChanged += new EventHandler(MyHandler);
        }
        else if (c is CheckBox)
        {
            ((CheckBox)c).CheckedChanged += new EventHandler(MyHandler);
        }
        else if (c is DateTimePicker)
        {
            ((DateTimePicker)c).ValueChanged += new EventHandler(MyHandler);
        }
        //Expand this to include any other type of controls your form 
        //has that you need to add the event to
    }
}
if else
块的第一部分检查
控件是否属于包含其他控件的类型。如果是,则使用该
控件中包含的新
System.Windows.Forms.Control.ControlCollection
调用AddEvents方法

if-else
块的第二部分检查控件c的类型,以使其适合于正确的类型,从而使用正确的事件。如果此时能够确定控件类型,那么前面创建的泛型事件将作为处理程序添加

最后,您需要调用此方法。最好的两个位置可能是在构造函数中或
Form.Load
事件中。放置它的最佳位置取决于您的具体情况。为了简单起见,我选择使用我的构造函数,现在看起来是这样的:

void MyHandler(object obj, EventArgs e)
{
    button1.Enabled = true;
}
public Form1()
{
    InitializeComponent();
    AddEvents(this.Controls);
}
这就是迭代控件和添加通用事件处理程序所需的全部内容。这段代码来自我创建的实际项目,我已经对其进行了测试,以确保其功能正常

编辑:我刚才还使用
控件在
分组框中测试了这个问题
面板中
分组框中
表单上的
面板中
对这个问题进行了测试。这就是利用递归的好处所在。只要正确设置
if…else…
块,就不需要知道嵌套的确切深度。它将根据需要进行深度调整,而不需要使用嵌套循环,也不需要知道确切的深度

EDIT2:作为旁注,此方法也可以在更细粒度的级别上使用。假设您有多个
GroupBox
控件,并且只希望将事件处理程序添加到“grpBox1”中的控件中。您可以调用
AddEvents(grpBox1.Controls)
而不是
AddEvents(this.Controls)
,这只会将事件处理程序应用于
grpBox1
中包含的控件


EDIT3:正如onemancat在评论中指出的那样,实际上并不完全需要检查控件是
GroupBox
还是
面板
等,因为所有控件都继承自基类
control
,该基类具有
controls
属性。您只需说
if(c.controls.Count>0)AddEvents(c.controls),即可检查
控件是否包含其他控件如果这将成为应用程序中的一个常见主题,您可以创建一些可重用代码,递归检查表单的所有控件,并连接事件处理程序。您可以将它放在InitiaizeComponent()之后

然后,在处理程序中,启用按钮:

void Button_Enable(object obj, EventArgs e)
{
    MyButton.Enabled = true;
}

您可以在许多表单上调用此方法,为用户创建一致的UI。这种方法的优点是,当您向表单添加新控件时,您(或下一位开发人员)不必记住将更改事件连接到正在启用的按钮,它将自动发生。

为供将来参考,请确保您所问的问题不是另一个问题的重复。请参阅前面的SO问题。我正在寻找一种方法,以避免对每个控件都执行此操作。。。所以这个问题实际上不是重复的?对不起,你的问题没有明确说明你想对每个控件都这样做,你问是否有类似“全局事件”的事情。如果这不是你真正想要的,你应该用一种更清晰的方式重新表述这个问题。对不起,我不是想吹毛求疵,但重要的是,如果你想要高质量的答案,人们能够以清晰简洁的方式理解你的目标。在我理解你的意思后,这是一个很好的建议(我最近更新了问题)…但这是我第一次讨论堆栈溢出…所以要软一点:p这看起来很棒!不幸的是,if语句中没有一个是真的,因为ctl只不过是一个GroupBox…我怎么也能连接到GroupBox中呢?你已经说过要使用递归,但实际上没有提供递归调用任何东西的代码。如果你没有他将答案转换为递归方法,以便在
控件中设置
控件
,我认为这将提供OP正在寻找的答案。(例如
面板
内的
按钮
,如果
面板
上的控件没有重复,则不会设置。)对于每个复选框,我也必须这样做,不是吗?@lorus有很多方法可以遍历
表单
的控件