C#-验证时突出显示错误的控件

C#-验证时突出显示错误的控件,c#,winforms,validation,error-handling,C#,Winforms,Validation,Error Handling,我正在尝试用try-catch验证windows窗体,到目前为止我成功了。我的目标是当有人忘记填补空白或输入错误时,catch返回带有警告的messagebox。现在,我在每个我想验证的控件上都有验证事件,所以当有人将其留空或格式不正确时,它会在控件旁边显示错误。到目前为止,这似乎还可以(至少对我来说),但我的问题是,如果用户甚至不点击一个框,它只会显示消息框,但不会突出显示错误的控件 下面是我的代码: private void createButton_Click(object sender,

我正在尝试用try-catch验证windows窗体,到目前为止我成功了。我的目标是当有人忘记填补空白或输入错误时,catch返回带有警告的messagebox。现在,我在每个我想验证的控件上都有验证事件,所以当有人将其留空或格式不正确时,它会在控件旁边显示错误。到目前为止,这似乎还可以(至少对我来说),但我的问题是,如果用户甚至不点击一个框,它只会显示消息框,但不会突出显示错误的控件

下面是我的代码:

private void createButton_Click(object sender, EventArgs e)
    {
        try
        {
            Book newBook = new Book(titleBox.Text, authBox.Text, Convert.ToInt32(yearBox.Text), Convert.ToInt32(editBox.Text), pubComboBox.Text, descBox.Text);
            bookList.Add(newBook);
            booklistListBox.DataSource = bookList;
        }
        catch (FormatException)
        {
            MessageBox.Show("You probably missed a gap or put in incorrect form");
        }

    }
以及那些验证事件:

 private void titleBox_Validating(object sender, CancelEventArgs e)
    {
         if (titleBox.Text.Trim() == String.Empty)
        {
            errorProvider.SetError(titleBox, "Title is required");
            e.Cancel = true;
        }
         else
        {
            errorProvider.SetError(titleBox, "");
        }
    }

    private void authBox_Validating(object sender, CancelEventArgs e)
    {
        if (authBox.Text.Trim() == String.Empty)
        {
            errorProvider.SetError(authBox, "Author is required");
            e.Cancel = true;
        }
        else
        {
            errorProvider.SetError(authBox, "");
        }
    }

    private void yearBox_Validating(object sender, CancelEventArgs e)
    {
        if (yearBox.Text.Trim() == String.Empty)
        {
            errorProvider.SetError(yearBox, "Year is required");
            e.Cancel = true;
        }
        else
        {
            errorProvider.SetError(yearBox, "");
        }
    }

    private void editBox_Validating(object sender, CancelEventArgs e)
    {
        if (editBox.Text.Trim() == String.Empty)
        {
            errorProvider.SetError(editBox, "Edition is required");
            e.Cancel = true;
        }
        else
        {
            errorProvider.SetError(editBox, "");
        }
    }

    private void pubComboBox_Validating(object sender, CancelEventArgs e)
    {
        if (pubComboBox.Text.Trim() == String.Empty)
        {
            errorProvider.SetError(pubComboBox, "Publisher is required");
            e.Cancel = true;
        }
        else
        {
            errorProvider.SetError(pubComboBox, "");
        }
    }

    private void descBox_Validating(object sender, CancelEventArgs e)
    {
        if (descBox.Text.Trim() == String.Empty)
        {
            errorProvider.SetError(descBox, "Description is required");
            e.Cancel = true;
        }
        else
        {
            errorProvider.SetError(descBox, "");
        }
    }
那么,有没有办法,我不知道,改变焦点或类似的东西,通过按下创建按钮来强制? 谢谢

尝试使用:


因此,这里的问题是,您希望在以下两种场景中突出显示它:

1) 当您离开该字段且其内容无效时(在本例中为空) 2) 当您单击“创建”按钮时,相关字段的内容无效

因此,我将创建一个
textBox\u checkIfEmpty(objectsender,EventArgs e)
方法:

private void textBox_checkIfEmpty(object sender, EventArgs e)
{
    var asTb = sender as TextBox;

    if (asTb != null && asTb.Text.Trim() == String.Empty)
    {
        errorProvider.SetError(asTb, "I'll leave it to you to abstract the error message appropriately");
        e.Cancel = true;
    }
    else
    {
        errorProvider.SetError(asTb, "");
    }
}
然后,您可以将此方法设置为所需控件上的
Validate
事件的处理程序,还可以从create按钮的处理程序调用相同的方法,在所需的
TextBox
实例中循环,并在每个实例上执行该方法

更新
J.Hudler的
ValidateChildren
解决方案将是一个更高效的(开发人员)挖掘尾部,而不是通过所需的控件进行循环。也就是说,如果表单有很多子项,并且只需要验证几个子项,那么仍然循环可能会有所帮助。这取决于你的具体情况。我唯一的另一个问题是
ValidateChildren
是否是无限递归的,或者它是否只向下一级(直接子代而不是所有子代)

当鼠标单击控件然后离开控件时,验证控件调用的事件。在您的情况下,当用户不单击控件时,它不会触发验证事件。您可以通过创建自己的函数并在创建事件时调用它们来实现这一点

private void button1_Click(object sender, EventArgs e)
    {

        textBox1_Validating(sender);
    }

    public void textBox1_Validating(object sender)
    {
        MessageBox.Show("validating");
        errorProvider1.SetError(textBox1, "provide");
    }

那么,这与我的try-catch版本有什么不同呢?这又如何为完全错误的控件提供反馈呢?他的方法是不同的,因为它会在单击“创建”按钮时自动检查控件,而不是依赖
FormatException
来告诉您出了问题。它实际上会触发您的验证事件。这一个运行良好,但当我有时间时,我也会尝试其他解决方案:-)但我想补充一点-由于我实现了此解决方案,我的表单将不会关闭,直到我正确地填补空白并保存它。这似乎是我正在寻找的,但我认为我的c#技能不太好,无法正确理解-我在每个控件上调用此CheckIfEmpty事件,这将替换我的验证事件?很抱歉这样说(dumm:-),所以现在,可能使用VisualStudio中的designer界面,您将每个单独的控件设置为其特定的事件处理程序进行验证。我要说的是,将它们的验证事件改为指向一个处理程序——让它更抽象。
private void button1_Click(object sender, EventArgs e)
    {

        textBox1_Validating(sender);
    }

    public void textBox1_Validating(object sender)
    {
        MessageBox.Show("validating");
        errorProvider1.SetError(textBox1, "provide");
    }