我的标准 winform 上的应用按钮在加载时被禁用,我想启用它,如果任何其他控件的状态发生更改(复选框、单选框、文本框等)
所以我可以浏览每个控件的事件并在那里启用按钮,但我想知道是否有更简单的方法来做到这一点,比如全局事件。
编辑 澄清:我正在寻找一种方法,我不必对每个控件都做某事。这样我就可以在以后添加更多控件而不必关心它们...
根据您的编辑,我已经修改了我的答案以包含您想要的功能。
首先,您需要一个看起来像这样的通用事件处理程序:
void MyHandler(object obj, EventArgs e)
{
button1.Enabled = true;
}
其中 button1 是您希望启用的按钮。
然后,您将需要一种递归方法,不仅可以遍历您的Form.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
块的第一部分检查是否属于control
包含其他控件的类型。如果是,则递归调用 AddEvents 方法,其中System.Windows.Forms.Control.ControlCollection
包含new control
。
该if else
块的第二部分检查控件 c 的类型,以便可以将其适当地转换为正确的类型,从而利用正确的事件。如果此时我们能够确定我们的控件类型,则将之前创建的通用事件添加为处理程序。
最后,您需要调用此方法。最好的两个地方可能是在您的构造函数中或在Form.Load
事件中。放置它的最佳位置将取决于您的具体情况。为了简单起见,我选择使用我的构造函数,现在看起来像这样:
public Form1()
{
InitializeComponent();
AddEvents(this.Controls);
}
这应该是您迭代控件和添加通用事件处理程序所需的全部内容。这段代码来自我创建的一个实际项目,我已经对其进行了测试以确保它具有正确的功能。
编辑:我也刚刚使用control
s inside of a GroupBox
inside of a Panel
inside of a GroupBox
inside of aPanel
进行了测试Form
。这就是利用递归的用处所在。只要您正确设置了if...else...
块,您就不需要知道确切的嵌套深度。它将尽可能深入,而无需使用嵌套循环并知道确切的深度。
EDIT2:作为旁注,此方法也可以在更细粒度的级别上使用。假设您有多个GroupBox
控件,并且您希望只将事件处理程序添加到“grpBox1”中的控件。您可以调用AddEvents(grpBox1.Controls)
而不是,AddEvents(this.Controls)
这只会将事件处理程序应用于grpBox1
.
EDIT3:正如 onemancat 在评论中指出的那样,实际上并不完全有必要检查控件是 aGroupBox
还是 aPanel
等,因为所有控件都继承自Control
具有Controls
属性的基类。您可以简单地检查是否Control
包含其他控件,if (c.Controls.Count > 0) AddEvents(c.Controls);
但是在想要选择要迭代的容器控件的情况下,有必要像我在示例中那样检查类型。如果没有必要如此细化,那么检查计数并且从不打扰类型检查或强制转换确实更有意义。
如果这将成为您的应用程序中的一个常见主题,您可以创建一些可重用的代码,递归地检查表单的所有控件,并将事件处理程序连接起来。你可以把它放在 InitiaizeComponent(); 之后。
// Programmatically wire up all Changed events to enable the button
foreach (Control ctl in this.Controls)
{
if (ctl is CheckBox)
{
((CheckBox)ctl).CheckedChanged += new EventHandler(Button_Enable);
}
else if (ctl is RadioButton)
{
((RadioButton)ctl).CheckedChanged += new EventHandler(Button_Enable);
}
// Here, wire up all other control types you'd like the button to respond to
}
然后,在处理程序中,启用按钮:
void Button_Enable(object obj, EventArgs e)
{
MyButton.Enabled = true;
}
您可以在许多表单上调用此方法来为用户创建一致的 UI。这种方法的优点是当您向表单添加新控件时,您(或下一个开发人员)不必记住将更改事件连接到启用的按钮,它会自动发生。