【问题标题】:Can't cause client side validation within a composite control不能在复合控件中导致客户端验证
【发布时间】:2012-02-17 23:46:25
【问题描述】:

我有一个自定义复合控件,其中包含一个文本框、一些验证器以及几个 UI 组件。我根本无法让客户端验证正常工作。回发后服务器端验证工作正常。我最终计划通过挂钩验证 API 将自定义 CSS 添加到验证失败的 TextBox,但我什至无法运行客户端验证。

由于这个控件是通用的,所以验证器不是从复合控件本身生成的,而是从外部传入的,如下所示。

    <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>

我指定了 persistchildren 属性(我相信是正确的),因此验证器实际上已添加到 Validators 属性中。这似乎也可以正常工作。

    [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 集合中并且可以正常工作。

我做错了什么?

【问题讨论】:

  • 通过一些实验,我发现这个问题肯定是因为我试图在复合控件之外创建验证器并将它们传递到自定义控件集合中。当我在 CreateChildControls 方法中简单地创建一个验证器时,它也可以正常工作。

标签: asp.net validation composite-controls


【解决方案1】:

这个问题是由于我试图在 asp.net 标记中创建验证器控件,然后稍后将它们传递给复合控件造成的。出于某种我不太明白的原因,验证器控件的生命周期似乎有点混乱,即使它们从未真正添加到控件树中,直到复合控件将它们放在那里。目的是它们将在标记中创建并由复合控件配置和加载。我只是使用模板系统而不是控件集合属性。这不是我想要的,因为可以添加其他控件,但它可以完美地工作,因为控件现在在 CreateChildControls 方法中实例化。现在看起来像这样。

    public ITemplate Validators { get; set; }

而不是

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

CreateChildControls 方法现在执行标准模板实例化

    this.ValidatorsTemplate.InstantiateIn(this.ValidatorContainer);

然后我递归地遍历 ValidatorContainer 控件(小心避免无限递归)寻找我通过设置 ControlToValidate 和其他一些东西配置的验证器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多