2

テキスト ボックス、いくつかのバリデータ、およびいくつかの UI コンポーネントを含むカスタム複合コントロールがあります。クライアント側の検証をまったく機能させることができません。サーバー側の検証は、ポストバック後に正常に機能します。私は最終的に、検証 API にフックすることによって、検証の失敗時に TextBox にカスタム CSS を追加することを計画していましたが、クライアント側の検証を実行することさえできません。

このコントロールはジェネリックであることを意図していたため、バリデーターは複合コントロール自体から生成されず、次のように外部から渡されます。

    <mycontrol:HighlightedTextbox ID="HighlightedTextbox1" runat="server" Label="test" CssClass="generalText" FocusedCssClass="highlightText" ErrorCssClass="errorText">
      <validators>
        <asp:RequiredFieldValidator ID="required1" runat="server" ErrorMessage="Field is required" EnableClientScript="true" />
      </validators>
      <prompttemplate><span>this is a prompt</span></prompttemplate>
    </mycontrol:HighlightedTextbox>

バリデーターが実際に Validators プロパティに追加されるように、persistchildren 属性を指定しました (適切だと思います)。それもうまく機能しているようです。

    [PersistChildren(true, true), ParseChildren(true), PersistenceMode(PersistenceMode.InnerProperty)]
    public abstract class BaseHighlightedControl<TControl> : CompositeControl
      where TControl : Control

標準の TextBox を TControl として指定し、テキスト プロパティを公開する派生コントロールがありますが、派生型が行うことはこれだけです。複合コントロールは、CreateChildControls メソッドに依存してコントロールを構築し、バリデータを構成します。CreateChildControls メソッドでバリデータを作成する複合コントロールの例を見たことがあるので、これはライフサイクルに適しているように思えます。

    public List<BaseValidators> Validators { get; private set; }

    /// <summary>
    /// Create the child controls
    /// </summary>
    protected override void CreateChildControls()
    {
        base.CreateChildControls();
        this.MainControl.ID = "HighlightControl";

        this.PromptTemplate.InstantiateIn(this.Prompt);
        this.Prompt.Style.Add(HtmlTextWriterStyle.Display, "inline");
        this.FieldLabel.Text = this.Label;

        if (!this.DesignMode)
        {
            this.Controls.Add(this.FieldLabel);
            this.Controls.Add(this.MainControl);
            this.Controls.Add(this.Prompt);
            AddValidators();
        }
    }

    private void AddValidators()
    {
        foreach (var validator in this.Validators.OfType<BaseValidator>())
        {
            validator.ControlToValidate = this.MainControl.ID;
            validator.ValidationGroup = this.ValidationGroup;
            validator.Display = ValidatorDisplay.Dynamic;

            this.Controls.Add(validator);
        }
    }

繰り返しますが、サーバー側の検証は問題なく行われます。JavaScript の Page_Validators コレクションには、バリデーターが含まれていません。私が制御できない範囲でマークアップに追加したバリデーターはすべて、javascript コレクションに正常に表示され、適切に機能します。

私は何を間違っていますか?

4

1 に答える 1

0

この問題は、asp.net マークアップ内に検証コントロールを作成し、後でそれらを複合コントロールに渡そうとしたことが原因でした。よくわからない何らかの理由で、バリデーター コントロールのライフ サイクルは、複合コントロールによってコントロール ツリーに配置されるまで実際にはコントロール ツリーに追加されなかったにもかかわらず、少し混乱しているように見えました。その意図は、それらがマークアップで作成され、複合コントロールによって構成およびロードされることでした。コントロール コレクション プロパティの代わりにテンプレート システムを使用しただけです。他のコントロールを追加できるため、私が望んでいたものとはまったく異なりますが、コントロールが CreateChildControls メソッドでインスタンス化されるようになったため、問題なく動作します。今はこんな感じです。

    public ITemplate Validators { get; set; }

それ以外の

    public List<BaseValidators> Validators { get; private set; }

CreateChildControls メソッドは、標準のテンプレートのインスタンス化を行うようになりました

    this.ValidatorsTemplate.InstantiateIn(this.ValidatorContainer);

次に、ValidatorContainer コントロールを再帰的にウォークし (無限再帰を避けるように注意してください)、ControlToValidate などを設定して構成するバリデーターを探します。

于 2012-02-21T20:33:18.670 に答える