我现在有一个表单
TabControl
包含一些
TabPage
每一个
制表
具有多个具有验证逻辑和适当的控件
ErrorProvider
在我的
OK_Button_Clicked
事件,我呼叫
Form.ValidateChildren()
以确定是否保存和关闭窗体。现在,假设我在选项卡1中有一个未通过验证的控件,但当前可见的选项卡是选项卡2。当用户按“确定”时,他将看不到窗体未关闭的原因。我希望能够自动切换到验证失败的选项卡,以便用户可以看到
错误提供程序
错误的指示。
一种方法是订阅
Validated
和
validating
所有适当控件的事件,以及知道每个控件都在哪个选项卡中,每当验证失败时,都可以构建验证失败的选项卡列表。因为没有
ValidationFailed
据我所知,事件是生成的,这可能很麻烦(例如,为每个控件定义一个布尔值,在验证前将其设置为false,在其上设置为true
验证的
事件)。即使我有这样一个事件,我也会被迫监听许多验证事件,每一个可能验证失败的控件一个,并在代码中维护未验证选项卡的列表。我要注意的是,直接订阅
制表
的验证事件不起作用,因为它们通过验证,即使其中包含的控件未通过验证。
另一种方法可以利用这样一个事实,即
制表
恰好是自定义控件。然后我可以让它们实现一个接口,比如:
interface ILastValidationInfoProvider
{
public bool LastValidationSuccessful {get; set;}
}
例如:
public MyControl : UserControl, ILastValidationInfoProvider
{
MyControl_Validing(object sender, object sender, CancelEventArgs e)
{
if (this.PassesValidation())
this.ErrorProvider.SetError(sender, null);
LastValidationSuccessful = true;
else
e.Cancel = true;
this.ErrorProvider.SetError("Validation failed!", null);
LastValidationSuccessful = false;
}
}
然后,在接到电话后
ValidateChildren
我可以使用如下代码:
public void OK_Button_Click
{
if (form.ValidateChildren())
this.Close()
else
foreach (TabPage tab in this.TabControl)
foreach (Control control in tab.Controls)
{
ValidationInfo = control as ILastValidationInfoProvider
if (ValidationInfo != null && !ValidationInfo.LastValidationSuccessful)
{
this.TabControl.SelectTab(tab);
return;
}
}
}
我更喜欢这种方法,但它不适合验证的控件不是自定义的情况。
我很乐意采用更好的方法。有什么想法吗?
编辑
我正在使用
Form.AutoValidate = EnableAllowFocusChange
(正如Chris在其WinForms手册中推荐的那样),因此焦点确实可以从未通过验证的控件(包括移动到其他选项卡)更改。我还更新了自定义控件的示例代码,以强调
错误提供程序
位于内部。