Выпадающий список findbyvalue внутри повторителя с использованием itemDatabound

Я пытаюсь настроить повторитель, в котором есть раскрывающиеся списки, значения которых выбираются при привязке их данных из массива, заполненного из базы данных с использованием linq.

Проблема, с которой я сталкиваюсь, заключается в том, что каждый из раскрывающихся списков имеет одно и то же выбранное значение при рендеринге, которое также оказывается последним значением внутри массива. Мне нужно, чтобы каждое выбранное значение соответствовало его метке, которая хранится в таблице из предыдущей отправки.

func.ConfigurePastClientSetting(label.Text, krmid) возвращает значение, равное одному из значений внутри ddl, которое было сохранено в базе данных из прошлых отправок форм.

Private Sub rptDropDownInfo_ItemDataBound(sender As Object, 
                e As System.Web.UI.WebControls.RepeaterItemEventArgs) _
                Handles rptDropDownInfo.ItemDataBound
Dim selected As New List(Of String)
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
        Dim ddl As DropDownList = e.Item.FindControl("ddlEloquaValues")
        Dim column As EbmsColumnLabel = DirectCast(e.Item.DataItem, EbmsColumnLabel)
        ddl.Items.AddRange(ddlELQ.Items.OfType(Of ListItem)().ToArray())
        ddl.ClearSelection()
        ddl.Items.FindByValue(func.ConfigurePastClientSetting(column.displayname, krmid)).Selected = True
selected.Add(ddl.SelectedItem.Value)
    End If
End Sub

Если я удалю ddl.ClearSelection, я получу ошибку «не может иметь более одного выбранного значения в раскрывающемся списке». Вот разметка:

 <asp:Repeater ID="rptDropDownInfo" runat="server">
                <HeaderTemplate><table><tr><td style="width:60px;padding-left:20px;">KRM</td><td></td><td>Eloqua</td></tr></table></HeaderTemplate>
                <ItemTemplate>
                <tr>
                    <asp:Label ID="lblColumnNames" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "DisplayName") %>'></asp:Label><td>map to</td>
                        <asp:DropDownList ID="ddlEloquaValues" runat="server">
                        </asp:DropDownList>
                    <td>
                        <asp:Label ID="lblWarningLabels" runat="server" Text=""></asp:Label></td></tr>
                </ItemTemplate>
                </asp:Repeater>

Я пытаюсь проверить первое (0) значение ddl.SelectedValue и получаю последний элемент в своем массиве:

Private Sub Page_PreRender(sender As Object, e As System.EventArgs) Handles Me.PreRender
    If IsPostBack Then
        Dim ddl As DropDownList = rptDropDownInfo.Items(0).FindControl("ddlEloquaValues")
        Dim check = ddl.SelectedItem.Value
    End If
End Sub

person stolbejj    schedule 14.09.2012    source источник
comment
Что такое func.ConfigurePastClientSetting(label.Text, krmid)? Также может быть полезно увидеть соответствующую разметку aspx. Вы должны использовать e.Item.DataItem чтобы получить базовый источник данных элемента.   -  person Tim Schmelter    schedule 15.09.2012
comment
@TimSchmelter Я внес изменения на основе ваших предложений, но все равно не повезло. Также я добавил еще несколько деталей.   -  person stolbejj    schedule 20.09.2012


Ответы (1)


Похоже, что все ваши DDL используют одни и те же экземпляры ListItems.

Таким образом, установка Selected=true для элемента выбирает его для всех DDL, которые его разделяют. Вот почему вы сталкиваетесь с проблемой при удалении ClearSelection.

Вы должны создать новые ListItems, если ваш запрос Linq создает новые ListItems через Select вместо возврата, например, существующих)

Надеюсь, это поможет.

ddl.Items.AddRange(ddlELQ.Items.OfType(Of ListItem)().ToArray())
ddl.Items.FindByValue(func.ConfigurePastClientSetting(column.displayname, krmid)).Selected = True

selected.Add(ddl.SelectedItem.Value)

должно быть (извините, синтаксис C#):

ddl.Items.AddRange(ddlELQ.OfType<ListItem>().Select(li=>new ListItem(){Text = li.Text,Value = li.Value}).ToArray())
ddl.SelectedIndex = ddl.Items.IndexOf(ddl.Items.FindByValue(func.ConfigurePastClientSetting(column.displayname, krmid)));

И вы должны удалить ClearSelection(), заменив его на ddl.Items.Clear(), если вы хотите предотвратить множественную привязку.

person jbl    schedule 26.09.2012
comment
это не решило. Я разместил менее запутанную версию моей проблемы здесь - person stolbejj; 27.09.2012
comment
@stolbejj Кроме того, вы должны установить свойство SelectedIndex DDL вместо установки свойства Selected элементов. Отредактировал мой ответ - person jbl; 27.09.2012