ListView using a DropDownList populated using code behind

I recently had to build a ListView to populate a linking table between Subjects and Series. This utilised drop down selectors to a series in both the insert and edit template- these weren’t populated by SQL or Object datasource, but using DataBinding in the code behind. This was a simple task, and one I had done before – althought almost always using an Object Data Source- but for some reason I got stuck on this one for a few hours! So I thought I would document the solution for future reference.

The issues I had occured on Edit. On the DropDownList I set the SelectedValue property to <%# Bind(“SeriesId”) %> but received an exception;

‘EditSeriesId’ has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value


    private IList<AZSubjectLink> SubjectData;

    protected void Page_Load(object sender, EventArgs e)
    {
        GetQueryStringData();
        LoadData();

        if (!Page.IsPostBack)
        {
            BindListView();
        }
    }

    private void GetQueryStringData()
    {
        if (Request.QueryString["id"] == null || !int.TryParse(Request.QueryString["id"], out _az_subject_id))
            Response.Redirect("AZSubjects.aspx", true);
        else
        {
            AZSubjectData data = new AZSubjectData();
            _this_subject = data.SelectById(_az_subject_id);
        }
    }

   // grab the data from the DAL
    private void LoadData()
    {
        AZSubjectLinkData data = new AZSubjectLinkData();
        SubjectData = data.SelectBySubjectId(_az_subject_id);
    }

   // perform databind on the actual list view and refill the insert drop downs
   private void BindListView()
    {
        lvAZSubjectSeriesLinks.DataSource = SubjectData;
        lvAZSubjectSeriesLinks.DataBind();

        DropDownList SeriesId = (DropDownList)lvAZSubjectSeriesLinks.InsertItem.FindControl("SeriesId");
        BindSeriesLookup(SeriesId, 0);
    }

    //this is called to populate the drop downs on the insert and edit rows
    private void BindSeriesLookup(DropDownList SeriesId, int selected_series_id)
    {
        List<int> taken_ids = SubjectData.Select(x => x.SeriesId).ToList();

        if (selected_series_id > 0) // an edit drop down box..
        {
            SeriesId.DataSource = Series.GetAllSeries()
                .OrderBy(x => x.Title).ToList();
        }
        else
        {  // this is an insert- make sure we dont list series we've already added
            SeriesId.DataSource = Series.GetAllSeries()
                .OrderBy(x => x.Title)
                .Where(x => !taken_ids.Contains(x.SeriesId)); //some linq to make sure we dont include records which have already been added!
        }

        SeriesId.DataTextField = "Title";
        SeriesId.DataValueField = "SeriesId";
        SeriesId.SelectedValue = selected_series_id.ToString();
        SeriesId.DataBind();
    }

    // standard handler to set the listviews edit index, then re-databind 
    protected void lvAZSubjectSeriesLinks_ItemEditing(object sender, ListViewEditEventArgs e)
    {
        lvAZSubjectSeriesLinks.EditIndex = e.NewEditIndex;
        BindListView();
    }

    protected void lvAZSubjectSeriesLinks_ItemDataBound(object sender, ListViewItemEventArgs e)
    {
        ListViewDataItem dataItem = (ListViewDataItem)e.Item;
        AZSubjectLink link = (AZSubjectLink)dataItem.DataItem;

        // check if the list view is in edit mode
        if (lvAZSubjectSeriesLinks.EditItem != null)
        {
            // check to see if this is the edit row!
            if (dataItem.DisplayIndex == lvAZSubjectSeriesLinks.EditIndex)
            {
                // find the drop down..
                DropDownList SeriesId = (DropDownList)e.Item.FindControl("EditSeriesId");

                // bind it - the selected id is passed to the control which does the binding of the drop downs
                BindSeriesLookup(SeriesId, link.SeriesId);
            }
        }

    }

The listview itself looks like this;

<asp:ListView ID="lvAZSubjectSeriesLinks" runat="server" InsertItemPosition="LastItem"
    OnItemInserting="lvAZSubjectSeriesLinks_ItemInserting" OnItemDeleting="lvAZSubjectSeriesLinks_ItemDeleting"
    OnItemUpdating="lvAZSubjectSeriesLinks_ItemUpdating" OnItemCanceling="lvAZSubjectSeriesLinks_ItemCanceling"
    OnItemEditing="lvAZSubjectSeriesLinks_ItemEditing" OnItemDataBound="lvAZSubjectSeriesLinks_ItemDataBound">
    <LayoutTemplate>
        <table width="100%" class="gridview" cellpadding="0" cellspacing="0">
            <tr class="header">
                <th id="Th1" runat="server">
                    Id
                </th>
                <th id="Th2" runat="server">
                    Series
                </th>
                <th id="Th3" runat="server">
                    Interest Range
                </th>
                <th id="Th4" runat="server">
                    Key Stage
                </th>
                <th id="Th5" runat="server">
                </th>
            </tr>
            <tr id="itemPlaceHolder" runat="server">
            </tr>
        </table>
    </LayoutTemplate>
    <ItemTemplate>
        <tr class='<%# Container.DataItemIndex % 2 == 0 ? "row" : "row alt" %>'>
            <td>
                <asp:Label ID="IdLabel" runat="server" Text='<%# Eval("Id") %>' />
            </td>
            <td>
                <asp:Label ID="TitleLabel" runat="server" Text='<%# Eval("Series.Title") %>' />
            </td>
            <td>
                <asp:Label ID="BookTitleLabel" runat="server" Text='<%# Eval("Book.CoverTitle") %>' />
            </td>
            <td>
                <asp:Label ID="InterestRangeLabel" runat="server" Text='<%# Eval("InterestRange") %>' />
            </td>
            <td>
                <asp:Label ID="KeyStageLabel" runat="server" Text='<%# Eval("KeyStage") %>' />
            </td>
            <td>
                <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="Delete" />
                <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="Edit" />
                <br />
                <%# ((((AZSubjectLink)Container.DataItem).SeriesId > 0)? "<a href='AZSubjectSeriesEdit.aspx?id=" + Eval("Id") + "'>Edit Exclusions &raquo;</a>" : "No Exclusions" ) %>
            </td>
        </tr>
    </ItemTemplate>
    <EditItemTemplate>
        <tr class='<%# Container.DataItemIndex % 2 == 0 ? "row" : "row alt" %>'>
            <td>
                <asp:Label ID="IdLabel" runat="server" Text='<%# Eval("Id") %>' />
            </td>
            <td>
                <asp:DropDownList ID="EditSeriesId" runat="server" Width="200" AppendDataBoundItems="true">
                    <asp:ListItem Value="0">None</asp:ListItem>
                </asp:DropDownList>
            </td>
            <td>
                <asp:TextBox ID="InterestRange" runat="server" Text='<%# Eval("InterestRange") %>' />
            </td>
            <td>
                <asp:TextBox ID="KeyStage" runat="server" Text='<%# Eval("KeyStage") %>' />
            </td>
            <td>
                <asp:Button ID="UpdateButton" runat="server" CommandName="Update" Text="Update" />
                <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="Cancel" />
            </td>
        </tr>
        <tr>
            <td colspan="3">
                <asp:Label ID="ErrorLabel" runat="server" Text=""></asp:Label>
            </td>
        </tr>
    </EditItemTemplate>
    <InsertItemTemplate>
        <tr style="">
            <td>
                New Record
            </td>
            <td>
                <asp:DropDownList ID="SeriesId" runat="server" Width="200" AppendDataBoundItems="true">
                    <asp:ListItem Value="0">None</asp:ListItem>
                </asp:DropDownList>
            </td>
            <td>
                <asp:TextBox ID="InterestRange" runat="server" Text='<%# Bind("InterestRange") %>' />
            </td>
            <td>
                <asp:TextBox ID="KeyStage" runat="server" Text='<%# Bind("KeyStage") %>' />
            </td>
            <td>
                <asp:Button ID="InsertButton" runat="server" CommandName="Insert" Text="Insert" />
                <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="Clear" />
            </td>
        </tr>
        <tr>
            <td colspan="3">
                <asp:Label ID="ErrorLabel" runat="server" Text=""></asp:Label>
            </td>
        </tr>
    </InsertItemTemplate>
    <EmptyDataTemplate>
        ...
    </EmptyDataTemplate>
</asp:ListView>
  1. #1 by Ray Toores on April 14, 2010 - 01:56

    Hello!

    I have searched the web for a while and there is nothing posted like your post, thanks for sharing.

    I created a listview that has a dropdown in the insert/item templates. All I want to do is when an option is selected in the dropdown from the insert template it will be selected in the item template after it has been added to the listview.

    Thanks for whatever help you may provide.

  2. #2 by shawson on April 14, 2010 - 10:10

    Hi Ray,

    Glad it was of some help- i spent a good while hunting through the web to get to this stage, so figured it would help someone!

    Hmm- sounds a little strange- why would you have a drop down box on your item template?

    Regardless in your item template it would just be a matter ofdoing somehting like;

    <asp:DropDownList ID=”myDropDown” runat=”server” SelectedValue=’<%# Bind(“myProperty”) %>’>
    … items …
    </asp:DropDownList>

    But this is no good if your drop down items arent static- if they are from a data soruce then you’de need to do it on itemDataBound of the list view- just after you set the databinding on your drop down, just set the selected value there in the code behind;

    myDropDown.DataSource = DAL.GetSomeData();
    myDropDown.DataBind();
    myDropDown.SelectedValue = my_value;

    Hope thats of some use!

    Shaw.

  3. #3 by Rajan on April 20, 2011 - 07:57

    Hi Shaw,

    It is a nice blog written by you, i was searching from long to figure out my problems.
    My all problems related to insert dropdown for new item is solved.
    Your blog is really nice and explanatory.

    Thanks for this great blog!

  4. #4 by gary on July 25, 2011 - 05:26

    Hey Bro – Thanks, you really saved my butt too. I spent all day on this blasted dropdown in edititem problem, 10:00 PM and I come across your post and have it straightened out in 10 minutes!

    cheers

  5. #5 by Kerrie Ahyou on June 8, 2012 - 07:21

    This really answered my problem, thank you!

(will not be published)