C#.NET桌面应用:控件焦点背景色切换代码仅对按钮生效的解决方法
问题原因
- 未递归遍历嵌套控件:原代码只遍历了窗体的直接子控件,而TextBox、ComboBox这类控件常放在Panel、GroupBox等容器内,没被绑定事件。
- 事件选择不合适:
GotFocus/LostFocus是低级焦点事件,部分控件(如TextBox)的焦点行为会导致这些事件触发不稳定,改用Enter/Leave事件更可靠。
修正代码
1. 递归遍历所有控件的方法
先写一个递归方法,遍历窗体中所有层级的控件:
private void AttachFocusEvents(Control parent) { foreach (Control ctrl in parent.Controls) { // 绑定Enter和Leave事件 ctrl.Enter += Ctrl_Enter; ctrl.Leave += Ctrl_Leave; // 如果当前控件是容器,递归遍历其子控件 if (ctrl.HasChildren) { AttachFocusEvents(ctrl); } } }
2. 修改事件处理逻辑
替换原来的GotFocus/LostFocus为Enter/Leave,逻辑保持一致:
private void Ctrl_Enter(object sender, EventArgs e) { var ctrl = sender as Control; if (ctrl != null) { // 存储原背景色到Tag ctrl.Tag = ctrl.BackColor; ctrl.BackColor = Color.Red; } } private void Ctrl_Leave(object sender, EventArgs e) { var ctrl = sender as Control; if (ctrl != null && ctrl.Tag is Color) { // 恢复原背景色 ctrl.BackColor = (Color)ctrl.Tag; } }
3. 在窗体构造函数中调用递归方法
替换原来的遍历代码,调用递归方法:
public BillingMetal(Billing _frm) { this.frm = _frm; InitializeComponent(); // 遍历所有控件(包括嵌套容器内的) AttachFocusEvents(this); }
额外说明
- 如果不希望某些控件触发该逻辑,可以在递归遍历的时候加判断(比如排除Label):
if (ctrl is Label) continue; - 若需要自定义焦点颜色,直接修改
Ctrl_Enter中的Color.Red即可。
内容的提问来源于stack exchange,提问作者s.k.Soni
相关产品推荐
相关产品推荐

