动态控制C#的验证器噩梦

时间:2009-05-14 11:45:23

标签: c# asp.net validation dynamic-controls

我需要将一个RequiredFieldValidator和RegularExpressionValidator添加到动态生成的表格单元格中的动态创建的文本框中,该表格单元格位于从主页创建的页面的内容区域中的Web用户控件中。

正如您可能猜到的那样,问题是尝试动态设置ControlToValidate属性以查看我动态创建的文本框。

经过一些研究后的代码:

  • 创建一个Panel(因为我听说ControlToValidate和Validator必须在同一个容器中)。这最初是一个占位符,但正在尝试下面列出的建议。
  • 创建文本框并设置其ID。
  • 将文本框添加到面板。
  • 创建RequiredFieldValidator。
  • 设置ControlToValidate的ID。我试图使用的值:

    • 控件的ID
    • 控件的ClientID
    • 以服务器附加到Web用户控件的子控件添加的文本为前缀的控件的ID
    • 以相同方式修改客户端ID
    • 控件的名称(关闭机会)
    • 控件的名称,前缀为服务器添加到控件名称的文本
    • 使用定制的递归FindControl方法尝试将新的Control对象强制转换为Textbox,然后使用其ID和ClientID
    • 控件的UniqueID
    • 使用上面详述的前缀进行修改
  • 将验证器添加到面板。
  • 将面板添加到tablecell。

毋庸置疑,我仍然无法说服Validator“看到”它应该验证的控件,而且我完全没有办法解决问题。

编辑:进一步的侦探工作让我发现页面在page_load事件结束之前没有问题。在构建页面的代码完成执行后,服务器似乎有问题。我开始怀疑我是否实际上将控件添加到命名容器中的时间太晚而不是太早。

有什么建议吗?

5 个答案:

答案 0 :(得分:1)

如何创建包含文本框和两个验证器的用户控件呢?然后你可以像往常一样通过Visual Studio设置ControlToValidate,然后动态地将这个新控件动态地添加到你的tablecell中。

答案 1 :(得分:1)

我在类似情况下使用了转发器:

<table>
<colgroup>
    <col style="white-space: nowrap;" />
    <col />
    <col />
</colgroup>
<asp:Repeater ID="InputFields" runat="server">
    <ItemTemplate>
        <tr>
            <td class="labelCell">
                <asp:Label id="FieldName" runat="server" Font-Bold="True" Text='<%# Eval("Name") %>'></asp:Label>:
            </td>
            <td class="fieldCell">
                <asp:TextBox id="FieldData" runat="server" autocomplete="off" />
            </td>
            <td class="errorCell">
                <asp:RequiredFieldValidator ID="FieldNameRequiredValidator" runat="server" CssClass="errorValidator" ErrorMessage='<%# Eval("Name") %> is required' 
                    ControlToValidate="FieldData" Display="Dynamic">&nbsp;&nbsp;&nbsp;</asp:RequiredFieldValidator>
                <asp:RegularExpressionValidator ID="FieldNameRegexValidator" runat="server" CssClass="errorValidator" ErrorMessage='A valid <%# Eval("Name") %> is required'
                    ControlToValidate="FieldData" Display="Dynamic" ValidationExpression='<%# Eval("RegEx") %>'>&nbsp;&nbsp;&nbsp;</asp:RegularExpressionValidator>
            </td>
        </tr>
    </ItemTemplate>
</asp:Repeater>

转发器创建一个“命名容器”,确保FieldData控件ID在容器中是唯一的。

答案 2 :(得分:0)

这是一个例子:

在设计时将ID控件添加到您的页面,ID =“PanelHolder”(或者您可以动态添加)。

然后动态创建控件并将它们添加到该面板,如下所示:

var myTextbox = new TextBox() {ID="myTextBox"};
PanelHolder.Controls.Add(myTextBox);
var validator = new RequiredFieldValidator() {ControlToValidate="myTextBox",Display=ValidatorDisplay.Dynamic,ErrorMessage="Required field"}
PanelHolder.Controls.Add(validator);

答案 3 :(得分:0)

只是几个问题:

  • 发布页面的控件是否会导致验证? (如果是,请确保它不在单独的验证组中)

  • 您确定没有验证吗?如果您没有设置验证器的ErrorMessage属性,可能很容易认为它没有做任何事情。 (我无法看到你在列表中设置它)

修改

如果您正在做这样的事情:

        Panel pTest = new Panel();

        TextBox tb = new TextBox();
        for (int i = 0; i < 2; i++)
        {
            tb.ID = "tbDynamicTextBox" + i;
            pTest.Controls.Add(tb );
            RequiredFieldValidator rfv = new RequiredFieldValidator();
            rfv.ControlToValidate = tb.ID;
            rfv.ErrorMessage = "Empty textbox";
            pTest.Controls.Add(rfv);
        }
        cell.Controls.Add(pTest);

然后您将收到错误,因为只有一个文本框实例将添加到控件集合中。 如果你移动'TextBox tb = new TextBox(); “在循环内部,它会没事的。

我不确定这是不是你的问题,但值得一试。

答案 4 :(得分:0)

我为网格内的texbox生成一个texbox和requiredfield验证器。

我首先尝试使用textbox的clientID作为requiredfield validator的controltovalidate属性 这给了无法找到控制错误 比我给texbox的ID作为controlto validate属性的requirefield验证器,它对我有用。下面的代码返回一个RegularExpressionValidator作为控件,作为方法的第一个参数。

private RegularExpressionValidator GetRegValidator(string itemId, string regExp)
    {
        RegularExpressionValidator _regVal = new RegularExpressionValidator();
        _regVal.ControlToValidate = itemId;
        _regVal.ValidationExpression = regExp;
        _regVal.ErrorMessage ="PropertyRegexDoesNotMatches";
        _regVal.Text = "*";
        _regVal.SetFocusOnError = true;
        _regVal.EnableClientScript = true;
        _regVal.ID = string.Format("{0}Validator", itemId);
        return _regVal;
    }