vb.netdrop-down-menurepeateritemdatabound

Dropdownlist findbyvalue inside repeater using itemDatabound


I'm trying to set up a repeater that features dropdowns that have their values selected upon their data being bound from an array populated from a db using linq.

The problem I'm having is that each of the dropdownlists have the same selected value upon rendering, which also happens to be the last value inside the array. I need each selected value to correspond with it's label, which is stored in a table from a previous submission.

func.ConfigurePastClientSetting(label.Text, krmid) returns a value that is equal to one of the values inside of ddl that has been stored in a database from past form submissions.

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

If I remove ddl.ClearSelection I get a "cannot have more than one selectedvalue in a dropdownlist error. Here is the markup:

 <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>

I try checking for the first(0) ddl.SelectedValue and I get the last item in my array:

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

Solution

  • Seems like all your DDLs are sharing the same ListItems instances.

    So setting Selected=true on an item selects it for all the DDLs that shares it. That is also why you encounter a problem when removing ClearSelection

    You should create new ListItems, by having your Linq query instante new ListItems through a Select instead of returning the existing ones for example)

    Hope this will help.

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

    selected.Add(ddl.SelectedItem.Value)

    should be (sorry, C# syntax) :

    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)));
    

    AND you should remove the ClearSelection(), replacing it with a ddl.Items.Clear() if you want to prevent multi-binding.