#asp.net #custom-controls #radiobuttonlist
#asp.net #пользовательские элементы управления #radiobuttonlist
Вопрос:
Я создал пользовательский RadioButtonList, который отображается как неупорядоченный список на основе аналогичного примера кода для пользовательского списка флажков.
Но по какой-то причине выбранный мной элемент не сохраняется при выполнении обратной передачи. Единственный метод, который я переопределил, — это Render-method:
[ToolboxData( "<{0}:ULRadioButtonList runat=server></{0}:ULRadioButtonList>" )]
public class ULRadioButtonList : RadioButtonList {
protected override void Render( HtmlTextWriter writer ) {
Controls.Clear();
string input = "<input id={0}{1}{0} name={0}{2}{0} type={0}radio{0} value={0}{3}{0}{4} />";
string label = "<label for={0}{1}{0}>{2}</label>";
string list = "<ul>";
if ( !String.IsNullOrEmpty( CssClass ) ) {
list = "<ul class="" CssClass "">";
}
writer.WriteLine( list );
for ( int index = 0; index < Items.Count; index ) {
writer.Indent ;
writer.Indent ;
writer.WriteLine( "<li>" );
writer.Indent ;
StringBuilder sbInput = new StringBuilder();
StringBuilder sbLabel = new StringBuilder();
sbInput.AppendFormat(
input,
""",
base.ClientID "_" index.ToString(),
base.UniqueID,
base.Items[index].Value,
(base.Items[index].Selected ? " checked=""" : "")
);
sbLabel.AppendFormat(
label,
""",
base.ClientID "_" index.ToString(),
base.Items[index].Text
);
writer.WriteLine( sbInput.ToString() );
writer.WriteLine( sbLabel.ToString() );
writer.Indent = 1;
writer.WriteLine( "</li>" );
writer.WriteLine();
writer.Indent = 1;
writer.Indent = 1;
}
writer.WriteLine( "</ul>" );
}
}
Я что-то забыл? Если я использую обычный ASP.NET RadioButtonList выбранный мной элемент сохраняется после обратной передачи, поэтому больше ничего не переопределяет мое значение; это как-то связано с пользовательским элементом управления.
Ответ №1:
Для того, чтобы такой подход работал, вы должны сопоставить name
(и id) атрибуты в вашей сгенерированной разметке с атрибутами RadioButtonList
. Итак, очевидной проблемой в вашем коде является значение name
атрибута — к нему следует добавить индекс для каждого переключателя, т.Е.
...
sbInput.AppendFormat(
input,
""",
base.ClientID "_" index.ToString(),
base.UniqueID index.ToString(), // <<< note the change here
base.Items[index].Value,
...
Также вместо «_» при генерации идентификатора следует использовать свойство ClientIdSeparator.
Наконец, я должен посоветовать вам отказаться от такого подхода к разработке элементов управления, потому что он по своей сути хрупкий, т. Е. он может сломаться, если произойдет изменение в том, как базовый ASP.NET элемент управления генерирует свою разметку. Например, в ASP.NET логика генерации идентификатора клиента может быть настроена, и поэтому ваша логика генерации идентификатора может работать некорректно, чтобы соответствовать исходной разметке, сгенерированной базовым элементом управления.
Комментарии:
1. Атрибуты name должны быть одинаковыми для всех кнопок radiobuttons в моем списке, потому что в противном случае я могу выбрать несколько кнопок radiobuttons, что не является целью radiobuttons.
2. @thomasvb, да — я был неправ, предлагая изменить атрибут name — я просто перепроверил и ASP.NET также генерирует атрибут с тем же именем. В таком случае, я думаю, что проблема может быть связана с генерацией идентификатора. Я предложу вам прокомментировать вашу реализацию рендеринга и посмотреть сгенерированный идентификатор для переключателя и сравнить его с тем, который сгенерирован вашей реализацией рендеринга.