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

更改Windows Form中ErrorProvider图标时抛出StackOverflowException异常

问题根因分析

你遇到的System.StackOverflowException和自定义ErrorProvider图标没有关联,是textBox1_Leave事件的处理逻辑触发了无限死循环导致的:
当textBox1失去焦点时触发Leave事件,你在事件逻辑中调用了textBox1.Focus()强制将焦点切回该控件,这个操作会再次触发textBox1的Leave事件,无限循环下最终触发栈溢出,报错出现在SetError行只是代码执行顺序的巧合,和图标资源无关。

解决方案

方案1(推荐):改用专门的输入验证事件

WinForm提供了Validating事件专门用于控件输入校验,不需要手动控制焦点即可实现校验不通过禁止失去焦点的效果,代码示例如下:

private void textBox1_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
    if(string.IsNullOrEmpty(textBox1.Text))
    {
        e.Cancel = true; // 校验不通过,禁止控件失去焦点
        errorProvider1.Icon = Properties.Resources.cross;
        errorProvider1.SetError(this.textBox1, "请输入用户ID");
    }
    else
    {
        errorProvider1.Icon = Properties.Resources.right;
        errorProvider1.SetError(this.textBox1, string.Empty); // 校验通过清除错误提示
    }
}

使用该方案需要确认textBox1的CausesValidation属性为true(默认值即为true)。

方案2:给Leave事件加防重复触发标志

如果你需要保留Leave事件的处理逻辑,可以新增一个标志位避免循环触发:

// 全局标志位
private bool _isLeaveProcessing = false;

private void textBox1_Leave(object sender, EventArgs e)
{
    if (_isLeaveProcessing) return;
    _isLeaveProcessing = true;
    
    try
    {
        if(string.IsNullOrEmpty(textBox1.Text))
        {
            textBox1.Focus();
            errorProvider1.Icon = Properties.Resources.cross;
            errorProvider1.SetError(this.textBox1, "请输入用户ID");
        }
        else
        {
            errorProvider1.Icon = Properties.Resources.right;
            errorProvider1.SetError(this.textBox1, string.Empty);
        }
    }
    finally
    {
        _isLeaveProcessing = false;
    }
}
验证方法

你可以先注释掉代码里的textBox1.Focus()行再运行,程序不会抛出异常即可确认你的图标资源引入操作是正确的。

内容的提问来源于stack exchange,提问作者Mahin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 23:54:01