C#WinForms ErrorProvider控件

C#WinForms ErrorProvider控件,c#,winforms,validation,errorprovider,C#,Winforms,Validation,Errorprovider,是否有人知道是否有办法获得ErrorProvider图标处于活动状态的控件列表。即,任何未通过验证的控件。我试图避免在表单中循环所有控件 我想显示某种消息,指示表单上有多少错误。由于我的表单包含选项卡,我试图让用户明白,非活动选项卡上可能存在错误,他们需要检查所有选项卡 谢谢 巴里你所说的这是一个相当棘手的解决方案 据我所知,没有办法自动做到这一点 您必须为每个控件维护一个标志,并在每次错误提供程序闪烁时手动设置它 可能是一个字典可以用来跟踪它。您必须首先使用SetError来设置控件上的错误,

是否有人知道是否有办法获得ErrorProvider图标处于活动状态的控件列表。即,任何未通过验证的控件。我试图避免在表单中循环所有控件

我想显示某种消息,指示表单上有多少错误。由于我的表单包含选项卡,我试图让用户明白,非活动选项卡上可能存在错误,他们需要检查所有选项卡

谢谢


巴里

你所说的这是一个相当棘手的解决方案

据我所知,没有办法自动做到这一点

您必须为每个控件维护一个标志,并在每次错误提供程序闪烁时手动设置它


可能是一个
字典
可以用来跟踪它。

您必须首先使用SetError来设置控件上的错误,对吗?如果你想把这些信息放在手边,也许你应该同时将它们存储在另一个集合中。例如,您可以将每个有错误的控件添加到哈希集中。

这属于“怎么可能不知道”的类别。调用ErrorProvider.SetError()的是您的代码,您应该可以轻松跟踪有多少错误仍然处于活动状态。这里有一个小助手类,使用其SetError()方法更新ErrorProvider。其Count属性返回活动错误数:

private class ErrorTracker {
  private HashSet<Control> mErrors = new HashSet<Control>();
  private ErrorProvider mProvider;

  public ErrorTracker(ErrorProvider provider) { 
    mProvider = provider; 
  }
  public void SetError(Control ctl, string text) {
    if (string.IsNullOrEmpty(text)) mErrors.Remove(ctl);
    else if (!mErrors.Contains(ctl)) mErrors.Add(ctl);
    mProvider.SetError(ctl, text);
  }
  public int Count { get { return mErrors.Count; } }
}
私有类错误跟踪器{
私有HashSet mErrors=新HashSet();
私人提供程序;
公共ErrorTracker(ErrorProvider提供程序){
mProvider=提供者;
}
public void SetError(控制ctl,字符串文本){
if(string.IsNullOrEmpty(text))merror.Remove(ctl);
否则如果(!mErrors.Contains(ctl))mErrors.Add(ctl);
mProvider.SetError(ctl,文本);
}
公共整数计数{get{return mErrors.Count;}}
}

只需将errorprovider作为全局变量而不是局部变量

public partial class MainForm
 {

    ErrorProvider errorProvider1 = new ErrorProvider();
    void Validate_Working()
    {
    errorProvider1.SetError(textbox1, "textbox is empty");
    errorProvider1.Clear();
    }


 }

这应该可以解决您的问题,因为您可能已经从其他方法(如btnCancel\u click)中删除了错误。
这对我很有效:)

今天我也遇到了同样的问题。我的解决方案是扩展ErrorProvider控件

请参阅下面的代码:

  public class MyErrorProvider : ErrorProvider
  {

    public List<Control> GetControls()
    {
      return this.GetControls(this.ContainerControl);
    }

    public List<Control> GetControls(Control ParentControl)
    {
      List<Control> ret = new List<Control>();

      if (!string.IsNullOrEmpty(this.GetError(ParentControl)))
        ret.Add(ParentControl);

      foreach (Control c in ParentControl.Controls)
      {
        List<Control> child = GetControls(c);
        if (child.Count > 0)
          ret.AddRange(child);
      }

      return ret;
    }
  }
公共类MyErrorProvider:ErrorProvider
{
公共列表GetControls()
{
返回this.GetControls(this.ContainerControl);
}
公共列表GetControls(控件父控件)
{
List ret=新列表();
如果(!string.IsNullOrEmpty(this.GetError(ParentControl)))
ret.Add(ParentControl);
foreach(ParentControl.Controls中的控件c)
{
List-child=GetControls(c);
如果(child.Count>0)
ret.AddRange(儿童);
}
返回ret;
}
}
您可以在表单中使用上述派生类,然后(假设myErrorProvider是表单中的类实例)可以通过调用以下命令获取表单中存在错误的所有控件:

List<Control> errorControls = myErrorProvider.GetControls();
List errorControls=myErrorProvider.GetControls();

谢谢你,汉斯。我有一种感觉,我必须做这样的事情。根据我的时间限制,我甚至可能创建自己的自定义errorprovider供将来使用。看起来这个功能应该可以在标准控件中使用——也许这就是我。再次感谢。嗯,是的。您明确禁止在问题中使用GetError()。小心你的要求。我想我对
ErrorProvider
类的期望有点过高。更好的ErrorProvider可以让您查询有错误的控件、检索计数等。不过,在示例中为+1。在SetError()方法中,您应该修改else子句,以便在使用数据绑定IDataErrorInfo接口时无需处理它。
List<Control> errorControls = myErrorProvider.GetControls();