2013-12-18 2 views
0

У меня есть код, который динамически создает форму ASP.NET на основе входного файла XML. Я пытаюсь добавить атрибуты к элементам управления во время выполнения, и у меня возникают некоторые странные проблемы с элементами списка.Добавление атрибута в список флажков во время выполнения

My Server Side код выглядит примерно так:

Me.radioButtonList = New RadioButtonList() 
Me.dropDownList = New DropDownList() 
Me.listControl = Nothing 
If controlType = "dropdown" Then 
    Me.listControl = Me.dropDownList 
Else 
    Me.listControl = Me.radioButtonList 
End If 
For Each ansElement As Answer In strAnswers 
    Dim newListItem = New ListItem(ansElement.AnswerText, ansElement.AnswerText) 
    If ansElement.ActionID IsNot Nothing AndAlso ansElement.ActionID <> "" Then 
     newListItem.Attributes.Add("actionID", ansElement.ActionID) 
    End If 
    Me.listControl.Items.Add(newListItem) 
Next 
Me.listControl.ID = controlID 
Me.Controls.Add(Me.listControl) 

Проблема заключается в том, когда я запускаю код и страница визуализации атрибуты добавляются к размаху исходя теге элемента управления не вход элемента сам. Таким образом, полученный HTML-код выглядит так.

<span actionID="1"> 
    <input id="lst_dynamic_MedIllnesses_0" name="ctl00$MainContentPlaceHolder$FormGenerator1$lst_dynamic_MedIllnesses$lst_dynamic_MedIllnesses_0" value="None" type="checkbox"> 
    <label for="lst_dynamic_MedIllnesses_0">None</label> 
</span> 

Что я должен сделать, чтобы получить ActionId атрибут для добавления фактического контроля входного и не пролет тегов?

Спасибо!

ответ

4

Предположим, вы говорите о RadioButtonList. Проблема заключается в том, что он использует элемент управления RadioButton и имеет 3 свойства атрибутов - Атрибуты, InputAttributes и LabelAttributes. Каждый из них используется для конкретного элемента html.

Проблема с RadioButtonList заключается в том, что он использует только свойство Attributes и не использует InputAttributes. Вот код метода RadioButtonList.RenderItem:

protected virtual void RenderItem(ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer) 
{ 
    if (repeatIndex == 0) 
    { 
    this._cachedIsEnabled = this.IsEnabled; 
    this._cachedRegisterEnabled = this.Page != null && !this.SaveSelectedIndicesViewState; 
    } 
    RadioButton controlToRepeat = this.ControlToRepeat; 
    int index1 = repeatIndex + this._offset; 
    ListItem listItem = this.Items[index1]; 
    controlToRepeat.Attributes.Clear(); 
    if (listItem.HasAttributes) 
    { 
    foreach (string index2 in (IEnumerable) listItem.Attributes.Keys) 
     controlToRepeat.Attributes[index2] = listItem.Attributes[index2]; 
    } 
    if (!string.IsNullOrEmpty(controlToRepeat.CssClass)) 
    controlToRepeat.CssClass = ""; 
    ListControl.SetControlToRepeatID((Control) this, (Control) controlToRepeat, index1); 
    controlToRepeat.Text = listItem.Text; 
    controlToRepeat.Attributes["value"] = listItem.Value; 
    controlToRepeat.Checked = listItem.Selected; 
    controlToRepeat.Enabled = this._cachedIsEnabled && listItem.Enabled; 
    controlToRepeat.TextAlign = this.TextAlign; 
    controlToRepeat.RenderControl(writer); 
    if (!controlToRepeat.Enabled || !this._cachedRegisterEnabled || this.Page == null) 
    return; 
    this.Page.RegisterEnabledControl((Control) controlToRepeat); 
} 

controlToRepeat что RadioButton, и он определяет только атрибуты свойства и игнорирует InputAttributes.

Я могу предложить способ исправить это - вы можете создать новый класс, который наследует RadioButtonList, и использовать его вместо стандартного. Вот код этого класса:

public class MyRadioButtonList : RadioButtonList 
{ 
    private bool isFirstItem = true; 

    protected override void RenderItem(ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer) 
    { 
     if (isFirstItem) 
     { 
      // this.ControlToRepeat will be created during this first call, and then it will be placed into Controls[0], so we can get it from here and update for each item. 
      var writerStub = new HtmlTextWriter(new StringWriter()); 
      base.RenderItem(itemType, repeatIndex, repeatInfo, writerStub); 
      isFirstItem = false; 
     } 

     var radioButton = this.Controls[0] as RadioButton; 

     radioButton.InputAttributes.Clear(); 
     var item = Items[repeatIndex]; 
     foreach (string attribute in item.Attributes.Keys) 
     { 
      radioButton.InputAttributes.Add(attribute, item.Attributes[attribute]);     
     } 
     // if you want to clear attributes for top element, in that case it's a span, then you need to call 
     item.Attributes.Clear(); 

     base.RenderItem(itemType, repeatIndex, repeatInfo, writer); 

    } 
} 

Немного описания - он имеет isFirstItem свойство, как контроль RadioButton, который используется ею создается во время выполнения в первом доступе, поэтому мы должны вызвать RenderItem, прежде чем мы сможем обновить Свойство InputAttrubutes. Поэтому мы вызываем его один раз и отправляем некоторый заглушка HtmlTextWriter, поэтому он не будет отображаться дважды. И затем после этого мы просто получаем этот элемент управления как Controls [0], и для каждого ListItem мы обновляем значения InputAttributes.

PS. Извините, я не использовал VB.Net, поэтому управление написано на C#

+0

Имеет ли элемент CheckboxList одну и ту же проблему, и, следовательно, необходимо также переопределить? –

+0

Также как я могу предотвратить его отображение атрибута в обоих местах? Теперь я получаю атрибуты в теге span и теге ввода. Таким образом, возникает другой набор проблем. –

+0

Да, CheckBoxList имеет ту же проблему. Но вместо RadioButtonList, который использует элемент управления RadioButton для элемента, CheckBoxList использует элемент управления CheckBox. И RadioButton наследует этот CheckBox. –

Смежные вопросы