TabControl
現在、いくつかのを含むフォームがありますTabPage
。それぞれTabPage
に、検証ロジックと適切なErrorProvider
sを備えたいくつかのコントロールがあります。私のOK_Button_Clicked
イベントではForm.ValidateChildren()
、フォームを保存して閉じるかどうかを判断するために電話をかけます。ここで、検証に失敗するコントロールがタブ1にあるが、現在表示されているタブはタブ2であるとします。ユーザーが[OK]を押すと、フォームが閉じない理由が視覚的に示されません。検証が失敗したタブに自動的に切り替えられるようにしたいので、ユーザーにErrorProvider
はエラーの表示が表示されます。
Validated
1つのアプローチは、すべての適切なコントロールのイベントとイベントをサブスクライブし、validating
検証に失敗するたびに、それぞれがどのタブにあるかを知ることで、検証に失敗したタブのリストを作成できます。ValidationFailed
私の知る限り、イベントは生成されないため、これは面倒な場合があります(たとえば、各コントロールにブール値を定義し、検証前にfalseに設定し、そのValidated
イベントでtrueに設定します)。そして、そのようなイベントがあったとしても、検証に失敗する可能性のあるコントロールごとに1つずつ、多くの検証イベントをリッスンし、コード内の未検証のタブのリストを維持することを余儀なくされます。ここで、の検証イベントに直接サブスクライブすることは機能しないことに注意する必要がありますTabPage
。これは、イベント内に含まれるコントロールが検証に失敗した場合でも、検証済みとして合格するためです。
TabPage
別のアプローチでは、私のコントロールがたまたまカスタムコントロールであるという事実を活用できます。次に、次のようなインターフェイスを実装させることができます。
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
(ChrisSellsがWinFormsの本で推奨しているように)なので、検証に失敗したコントロール(他のタブへの移動を含む)からフォーカスを実際に変更できます。ErrorProvider
また、カスタムコントロールのサンプルコードを更新して、が内部に存在するという事実を強調しました。