2012-02-17 21 views
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> 

我有persistchildren属性指定(我相信适当),以便验证器实际上添加到Validators属性。这似乎也工作得很好。

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

我有一个派生的控制,指定标准的文本框为的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集合中,并且工作正常。

我在做什么错?

+0

通过一个小实验,我发现,因为我想创建复合控件外的验证,并将它们传递到定制控件集合问题肯定造成。当我在CreateChildControls方法中简单地创建一个验证器时,它也可以正常工作。 – Devin 2012-02-21 17:36:45

回答

0

该问题是由于我尝试在asp.net标记内创建验证控件,然后将它们传递到复合控件中引起的。出于某种原因,我不太明白,验证控件的生命周期似乎有点乱了,即使他们从来没有真正加入到控制树,直到复合控件把它们放在那里。目的是它们将在标记中创建并由复合控件进行配置和加载。我只是使用模板系统而不是控件集合属性。由于控件现在可以在CreateChildControls方法中实例化,所以它不是我想要的,因为可以添加其他控件。它现在看起来像这样。

public ITemplate Validators { get; set; } 

代替

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

CreateChildControls方法现在这样的标准模板实例

this.ValidatorsTemplate.InstantiateIn(this.ValidatorContainer); 

我然后递归走ValidatorContainer控制(小心,以避免无限递归)寻找验证我通过设置ControlToValidate和其他一些东西进行配置。