Кошмар валидатора на динамическом управлении C#
-
21-08-2019 - |
Вопрос
У меня есть требование добавить RequiredFieldValidator и RegularExpressionValidator в динамически создаваемое текстовое поле в динамически создаваемой ячейке таблицы внутри пользовательского веб-элемента управления в области содержимого страницы, созданной из мастера.
Проблема, как вы, наверное, догадались, заключается в попытке динамически установить свойство ControlToValidate для просмотра моего динамически созданного текстового поля.
После некоторого исследования кода теперь:
- Создает панель (как я слышал, ControlToValidate и Validator должны находиться в одном контейнере).Изначально это был заполнитель, но мы пробовали вариант, указанный ниже.
- Создает текстовое поле и устанавливает его идентификатор.
- Добавляет текстовое поле на панель.
- Создает RequiredFieldValidator.
Устанавливает идентификатор ControlToValidate.Значения, которые я пытался использовать:
- Идентификатор элемента управления
- ClientID элемента управления
- идентификатор элемента управления с префиксом добавленного текста, который сервер добавляет к дочерним элементам управления веб-пользовательского элемента управления.
- идентификатор клиента изменен таким же образом
- название элемента управления (на всякий случай)
- имя элемента управления с префиксом текста, который сервер добавляет к именам элементов управления
- использование специального рекурсивного метода FindControl в попытке привести новый объект Control к Textbox, а затем использовать его идентификатор и ClientID
- УникальныйID элемента управления
- то же самое, модифицированное с префиксом, как описано выше
- Добавьте валидатор на панель.
- Добавьте панель в tablecell.
Излишне говорить, что я до сих пор не могу убедить Валидатор «увидеть» элемент управления, который он должен проверять, и у меня совершенно нет новых способов решения проблемы.
РЕДАКТИРОВАТЬ:Дальнейшая детективная работа привела меня к тому, что на странице не возникает проблем до тех пор, пока не завершится событие page_load.Кажется, на сервере возникла проблема после завершения выполнения кода построения страницы.Я начинаю задаваться вопросом, не слишком ли поздно я добавляю элементы управления в именованные контейнеры, а не слишком рано.
Какие-либо предложения?
Решение
А как насчет создания пользовательского элемента управления, содержащего текстовое поле и два валидатора?Затем вы можете установить ControlToValidate
через Visual Studio, как обычно, а затем динамически добавить этот новый элемент управления в свою ячейку таблицы.
Другие советы
Я использовал репитер в аналогичной ситуации:
<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"> </asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="FieldNameRegexValidator" runat="server" CssClass="errorValidator" ErrorMessage='A valid <%# Eval("Name") %> is required'
ControlToValidate="FieldData" Display="Dynamic" ValidationExpression='<%# Eval("RegEx") %>'> </asp:RegularExpressionValidator>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
Повторитель создает «контейнер именования», который гарантирует уникальность идентификатора элемента управления FieldData внутри контейнера.
вот пример:
Добавьте элемент управления Panel на свою страницу во время разработки с идентификатором = «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);
Всего пара вопросов:
Вызывает ли элемент управления, который отправляет страницу обратно, проверку?(если да, убедитесь, что он не находится в отдельной группе проверки)
Вы уверены, что проверка не происходит?Если вы не установите свойство 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();' часть внутри цикла, хотя все будет хорошо.
Не уверен, что это ваша проблема, но попробовать стоит.
Я генерирую текстовое поле и валидатор обязательного поля для этого текстового поля внутри сетки.
Сначала я попытался использовать ClientId TextBox в качестве свойства ControlTovalidate of EdanceField Validator, который не мог найти ошибку управления, чем ID Texbox в качестве свойства Controltovalidate of Edenadfield Validator, и он был обработан для меня. Приведенный ниже код возвращает 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;
}