C# 将事件添加到表单中的所有标签
我想使用下面的代码将click、mouseleave和mouseenter事件添加到表单中的所有标签中。但是我在form_load上调用addeventtoalllabels,但它不会向标签添加事件C# 将事件添加到表单中的所有标签,c#,.net,C#,.net,我想使用下面的代码将click、mouseleave和mouseenter事件添加到表单中的所有标签中。但是我在form_load上调用addeventtoalllabels,但它不会向标签添加事件 public void setColor() { if (clickedLabel != default(Label)) clickedLabel.BackColor = Color.Yellow;
public void setColor()
{
if (clickedLabel != default(Label))
clickedLabel.BackColor = Color.Yellow;
//Resetting clicked label because another (or the same) was just clicked.
}
void addeventtoalllabels()
{
foreach (Label c in this.Controls.OfType<Label>())
{
try
{
c.Click += (sender, e) => {
setColor();
Label theLabel = (Label)sender;
clickedLabel = theLabel;
};
c.MouseEnter += (sender, e) =>
{
Label theLabel = (Label)sender;
if (theLabel != clickedLabel)
theLabel.BackColor = Color.Red;
};
c.MouseLeave += (sender, e) =>
{
Label theLabel = (Label)sender;
if (theLabel != clickedLabel)
theLabel.BackColor = Color.Yellow;
};
}
catch { }
}
}
听起来问题在于某些标签位于其他容器控件内,因此在执行此操作时不会对其进行迭代。controls.OfType所有控件对象都有一个控件集合 解决此问题的一种方法是递归地查看所有控件的控件集合,以便可以找到属于其他容器控件的子标签对象 以下是三种方法: AddEventsToLabel接受Label控件并向其添加事件。 AddEventToChildLabels接受一个控制参数并检查它是否是一个标签。如果是,则将其传递给上面1中的方法。否则,它会递归地调用传入的子控件的每个子控件。 AddEventsToAllLabels用于启动流程-此方法调用上面2中的方法,将表单本身作为父控件传递给此控件。 这样我们就可以迭代表单上的每个控件,包括其他容器控件中的所有控件:
private void AddEventsToAllLabels()
{
AddEventsToChildLabels(this);
}
private void AddEventsToChildLabels(Control parent)
{
if (parent is Label)
{
AddEventsToLabel(parent as Label);
}
else
{
foreach (Control control in parent.Controls)
{
AddEventsToChildLabels(control);
}
}
}
private void AddEventsToLabel(Label label)
{
label.Click += (sender, e) => {
SetColor();
Label theLabel = (Label)sender;
clickedLabel = theLabel;
};
label.MouseEnter += (sender, e) =>
{
Label theLabel = (Label)sender;
if (theLabel != clickedLabel) theLabel.BackColor = Color.Red;
};
label.MouseLeave += (sender, e) =>
{
Label theLabel = (Label)sender;
if (theLabel != clickedLabel) theLabel.BackColor = Color.Yellow;
};
}
请注意,最好先删除事件处理程序,然后再添加它,以防此方法被多次调用。否则,如果您多次将同一事件处理程序挂接到同一事件,则每次引发该事件时,处理程序将执行添加该事件的次数
例如:
private void AddEventsToLabel(Label label)
{
label.Click -= LabelClick;
label.MouseEnter -= LabelMouseEnter;
label.MouseLeave -= LabelMouseLeave;
label.Click += LabelClick;
label.MouseEnter += LabelMouseEnter;
label.MouseLeave += LabelMouseLeave;
}
private void LabelClick(object sender, EventArgs e)
{
SetColor();
Label theLabel = (Label)sender;
clickedLabel = theLabel;
}
private void LabelMouseEnter(object sender, EventArgs e)
{
Label theLabel = (Label)sender;
if (theLabel != clickedLabel) theLabel.BackColor = Color.Red;
}
private void LabelMouseLeave(object sender, EventArgs e)
{
Label theLabel = (Label)sender;
if (theLabel != clickedLabel) theLabel.BackColor = Color.Yellow;
}
永远不要使用空的try-catch。调试这个时会发生什么?标签是否在面板中?它只能修改表单上的标签。比如说,面板上没有任何标签。编写此代码的自然方法是使其递归,以c.Controls作为参数再次调用。@DervişKayımbaşıoğlu我在initialisecomponent和formşloadIt之后调用它,它对我来说很好。这些标签是否在其他容器控件中?您只是在迭代this.Controls。如果确实希望表单中的所有标签控件具有相同的行为,则最好创建一个标签子类并在UI中使用它。请参阅标记副本的第一个答案。如果您不想这样做,那么您需要递归地搜索表单控件,以查找所需类型的控件,即标签,并在每个控件上添加事件处理程序。请参阅标记副本的第二个答案。