You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#.NET桌面应用:控件焦点背景色切换代码仅对按钮生效的解决方法

解决C# WinForms控件焦点变色仅对Button生效的问题

问题原因

  1. 未递归遍历嵌套控件:原代码只遍历了窗体的直接子控件,而TextBox、ComboBox这类控件常放在Panel、GroupBox等容器内,没被绑定事件。
  2. 事件选择不合适: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:34:57