2

私はあなたに少し謎を提示します...次のコントロールは、何があっても毎回検証に失敗することを目的としていますが、そうではありません:

public class Test : CompositeControl
{
    protected override void CreateChildControls()
    {
        Controls.Clear();
        CreateControlHierachy();
        ClearChildViewState();
    }

    void CreateControlHierachy()
    {
        var validator = new CustomValidator
        {
            ErrorMessage = "Can't do that!"
        };

        validator.ServerValidate += (sender, e) =>
        {
            e.IsValid = false;
        };

        Controls.Add(validator);
    }
}

この問題を「修正」するには、CreateControlHierachyに次の行を追加すると、すべてが期待どおりに機能します。

Controls.Add(new TextBox());

コントロールはweb.configに登録され、次のような単純なページに配置されます。

<uc:Test runat="server" />

ポストバックイベントでデバッガーを使用すると、次のことがわかります。

  • 予想通り、バリデーターはページのコントロール階層にあります。
  • バリデーターはPage.Validatorsに登録されていません。
  • Page.IsValidとvalidator.IsValidはどちらも引き続きtrueです。

TextBoxはバリデーターにどのような影響を及ぼしますか?これを修正する正しい方法は何ですか?

4

1 に答える 1

1

私はこれについて考えられる説明を見つけました。TextBoxが存在すると、IPostbackDataHandlerである子コントロールがコントロールに追加されます。投稿データをロードするには、ページは最初にFindControlを呼び出してコントロールを見つける必要があります。FindControlがその機能を実行すると、最終的にはコントロールのControlsコレクションにアクセスします。コントロールはCompositeControlであるため、CreateChildControlsを呼び出すEnsureChildControlsを呼び出します。

これはすべて、検証の前に行われます。TextBoxを取り出すと、検証前にControlsコレクションにアクセスできなくなるため、検証後(おそらく事前レンダリング中)までバリデーターは作成されません。

バリデーターは検証段階では存在しないため、呼び出されません。検証が行われる前に、EnsureChildControlsへの呼び出しを追加することをお勧めします。

    protected override void OnLoad(EventArgs e)
    {
        EnsureChildControls();
        base.OnLoad(e);
    }
于 2009-07-31T03:54:46.500 に答える