ListControl.AppendDataBoundItems Property in ASP.NET 2.0

Bilal Haidar recently did a nice blog post that called out a small but useful new feature on the ListControl base class (which is the base control for a variety of input controls) in ASP.NET 2.0.  Specifically it is a property called "AppendDataBoundItems", and it controls whether the items within an existing list are replaced or appended-to when the control is databound (with ASP.NET 1.1 the items were always replaced).

Here is a simple example of where this comes in handy:

<asp:DropDownList ID="DropDownList1" AppendDataBoundItems="true" runat="server" DataSourceID="SqlDataSource1" DataTextField="state" DataValueField="state">

    <asp:ListItem Text="(Select a State)" Value="" />   

</asp:DropDownList>

 

<asp:SqlDataSource ID="SqlDataSource1" runat="server"

                   ConnectionString="<%$ ConnectionStrings:pubsConnectionString %>"

                   SelectCommand="SELECT DISTINCT [state] FROM [authors]">

</asp:SqlDataSource>

In the above code I'm databinding the unique list of states in the pubs:authors table to an <asp:dropdownlist> control.  For convenience sake I'm using the SqlDataSource control todo this -- although I could alternatively use either the ObjectDataSource to bind it against a class or just manually write code against the control's DataSource property. 

What is new in ASP.NET 2.0 is that I can also specify some additional drop-down values -- such as an initial "(Select a State)" value -- that are not part of the databound result.  Because the "AppendDataBoundItems" property is set to true, after databinding I will then have a dropdownlist whose first value is "(Select a State)" -- followed by the unique states currently in the authors table.

If I wanted to add validation, I could optionally then use a <asp:requiredfieldvalidator> control to point at the <asp:dropdownlist>:

<asp:RequiredFieldValidator ID="RequiredFieldValidator1"

                            runat="server"

                            ErrorMessage="Please select a state"

                            ControlToValidate="DropDownList1">

</asp:RequiredFieldValidator>

This would then output an error message "Please select a state" if the user tried to submit without choosing something other than the default "(Select a State)" item.  Making them choose a non-default value this way forces them to make a concious choice as to which item to pick.

Special thanks to Bilal for calling out this new feature (I actually didn't know it existed until I read it a few minutes ago <g>),

Scott

 

21 Comments

  • looking forward to installing this.

  • Fantastic!!! I was just about to write code for this everywhere. Thanks!

  • Scott, I am honored to be mentioned in your blog!!



    Regards

  • Huh? Why don't you just use the ListItems.Insert() method then?

  • Thats a great property. But what if you whan to localize the &quot;select a state text&quot;. You can&#180;t have a localize control as a child to listitem ?

  • There is another feature that is added too the listitem class. The property Enabled. This is new to to Asp.net 2.0



  • Or the PromptText property in EasyListBox :)



    Cool tip, Bilal; I was wondering when this would show up in the standard dropdown control!

  • Hi Per,



    Have you tried to use the new ASP.NET 2.0 localization features with a ListItem? I would think that this would work (and so you could localize the &quot;Select a State&quot; property) -- although I haven't tried it myself yet.

    Thanks,



    Scott

  • excellent.

    I see.When add the AppendDataBouldItems property,ASP.NET will add the static items first and second for the dynamic items.

    very nice.thanks

  • Hi K,

    The data will actually be populated on-demand (the first time it is accessed - if not then before prerender).

    You can handle the SQLDataSource's "Selected" event that fires after the data is selected. You could then use this to consistently code against the data returned.

    Hope this helps,

    Scott

  • Hello Scott,

    I also have a problem setting the selected items in a checkboxlist using AppendDataBoundItems in a formview. The problem is finding the actual value of a field in the sqldatasource.

    ASPX:






    Code behind:

    (In sub FormView1_DataBound:)

    Dim row As FormViewRow = FormView1.Row
    Dim checkboxList As CheckBoxList = CType(row.FindControl("cblFuncties"), CheckBoxList)
    checkboxList.DataSource = Roles.GetAllRoles()
    checkboxList.DataBind()

    I would like to set the selected items, by calling a sub:

    Private Sub SetCheckboxList(ByVal controlname As CheckBoxList, ByVal myvalue As String)
    Dim Item As ListItem

    For Each Item In controlname.Items
    If InStr(myvalue, CStr(Item.Value)) Then
    Item.Selected = True
    End If
    Next

    End Sub

    The controlname will be "cblFuncties" And myvalue is the value of column "visibleForRoles" in the SQLdatasource. I thought I could retrieve this value using:

    Dim dv As DataView = CType(SqlDataSourceDetails.Select(DataSourceSelectArguments.Empty), DataView)
    Dim dr As DataRow = dv.Table.Rows(0)
    Dim myvalue As string = dr("visibleForRoles").ToString

    This last part is not working and I don't know which event to use to get the value.

    With regards,

    Jeroen

  • Hi Jeroen,

    Any chance you could send me a simple sample as a .zip file in email? I can then take a look and help.

    Thanks,

    Scott

  • Hi Ray,

    Any chance you could send me an email with this question (along with a code snippet)? I can then loop in a few folks to help.

    Thanks,

    Scott

  • Hi Scott

    Did you manage to find a solution to Rays issue as I seem to me having the same problem. ie I can limit the records in my second dropdown list based on the first as long as I do not have the appenddatabounditems set to true. As soon as I set the second dropdownlist's appenddatabounditems to true it looses its ability to filter.

  • Hi Scott

    Having the same sort of problem as Ray I think. I have two dropdown boxes the second of which I want to filter down to only show related records from the first when something is selected. I want to have a "Show All" entry at the top of both boxes but as soon as I set the appenddataboundobjects to true it stops the filter on the second box. Did you ever manage to come up with a solution to rays problem. Cheers for any help.

  • Hi Carl/Carlos,

    Can you send me email (scottgu@microsoft.com) with more details about the issue and ideally a simple repro? I can the loop someone in from the data team to hopefully help.

    Thanks,

    Scott

  • Was there ever a solution provided to the issues that Ray/Carl/Carlos presented? I am having the same problem, and have not been able to make anything work, other than adding a dummy entry in the db.

  • I seemed to work around the problem above by clearing the items of the second drop down list on the SelectedIndexChanged event of the first drop down list. &nbsp;I then insert my static item back at index 0 also in then SelectedIndexChanged event of the first drop down list.

  • My problem with the AppendDataBoundItems property is that if you have the same set of items bound in multiple ObjectDataSources and make changes to those items, ASP.NET will leave the old set of items in the DropDownList when you do another DropDownList.DataBind() when it appends the updated set.

    Example:
    I have a DropDownList with AppendDataBoundItems set to true bound to a categories table and a GridView bound to the categories table, both via separate data sources.

    When I update the categories and call DataBind() on the DropDownList, it doesn't clear out its Items list before doing the data binding but simply appends them to its list.

    I worked around it by manually clearing the DropDownList, appending the manually inserted items to the list again, and then calling DataBind(). Another way to work around this that I just thought of while writing this comment was to do the appends in the DropDownList's DataBound event.

  • Here's a workaround to the sequential dropdownlist binding and selected default problems

    Two successive dropdown list in a Table of "Artists" With many StewardTokens
    Modify the configured DataSource controls by hand

    SELECT "" AS [LastName] FROM [Artists] UNION SELECT [LastName] FROM [Artists] WHERE ([StewardToken] = ?) ORDER BY [LastName]
    SELECT"" AS [FirstName] FROM [Artists] UNION SELECT [FirstName] FROM [Artists] WHERE (([StewardToken] = ?) AND ([LastName] = ?)) ORDER BY [FirstName]

    VBasic

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim pageStewardUserName = CType(Session.Item("sessionStewardUserName"), String)
    lblStewardName.Text = pageStewardUserName
    Dim pageStewardUserToken = CType(Session.Item("sessionStewardToken"), String)
    lblStewardUserToken.text = pageStewardUserToken

    If IsPostBack Then
    lblLastName.Text = ddlLastName.SelectedValue
    lblFirstName.Text = ddlFirstName.SelectedValue

    End If

    End Sub

  • Well this whole thing of "AppendDataBoundItems = true" to add a static item to a dropdown works fine for trivial cases, but as soon as you have to deal with a dropdown that filters according to another one, you are exposed to the obvious bug that subsequent postbacks will append and append and append records. Many people have seemed to run into this here. What could be the .NET 2.0 way of dealing with it (ie without using code-behind at all) ?

Comments have been disabled for this content.