ASP.NET Listbox selection problem - help!

Associate
Joined
24 Jul 2003
Posts
1,420
Location
West Mids
I've got a listbox that's populated from a SQL datasource. The user can remove items from this list (and subsequently the database) by clicking on a button that runs a sub to delete the selected item in the list from the database.

The problem is that no matter what happens, when the delete sub fires on page post back, the listbox deletes the first item in the list (index 0) regardless of what was actually selected. I even disabled the delete to see what was happening and sure enough, the page stubbornly thinks that index 0 was selected on post back.

I've got no idea why this is happening since I've got virtually identical functions on other pages doing the same thing and they don't exhibit the problem. The listbox doesn't get repopulated on post back so that's not the problem.

Does anyone have any ideas why this might be happening?
 
Yes

I've even made a second very basic page to see if I could replicate the problem and sure enough, exactly the same is happening:

Code:
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Data" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    Dim sqlConn As SqlConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("inductionConn").ConnectionString)
    Dim templateId As Integer = 4
    Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs)
        If Not Page.IsPostBack Then
            populate()
        End If
    End Sub
    
    Sub populate()
        Dim sqlStr As String = "SELECT templateId, category " & _
                               "FROM categories " & _
                               "WHERE templateId = @templateId"
        Dim sqlComm As SqlCommand = New SqlCommand(sqlStr, sqlConn)
        sqlComm.Parameters.Add(New SqlParameter("@templateId", SqlDbType.Int))
        sqlComm.Parameters("@templateId").Value = templateId
        Dim dataReader As SqlDataReader
        Try
            sqlConn.Open()
            dataReader = sqlComm.ExecuteReader()
            While dataReader.Read()
                Dim listItem As New ListItem
                listItem.Text = dataReader.Item("category")
                listItem.Value = dataReader.Item("templateId")
                ListBox1.Items.Add(listItem)
            End While
        Catch ex As Exception
            Response.Write(ex.Message)
        Finally
            sqlConn.Close()
        End Try
    End Sub
    
    Sub showSelectedItem(ByVal Sender As Object, ByVal e As EventArgs)
        Response.Write(ListBox1.SelectedItem)
    End Sub
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
        <asp:ListBox ID="ListBox1" runat="server" Width="200"></asp:ListBox>
    
        <asp:Button ID="Button1" runat="server" Text="Button" onClick="showSelectedItem"/>
    
    </div>
    </form>
</body>
</html>

Everything is fine apart from the fact it just doesn't return the correct selected item. I've done some googling and it seems that several people have encountered the same problem. However, none of them have come up with a solution either.

The problem ONLY occurs when populating from the database and not if I manually add ListItems, or even defined as part of the actual list box - really has me confuzzled :(
 
Last edited:
It's probably something to do with the way you’re binding the control. You should never really need to loop through the data reader manually creating the list items.

I’d have a separate method that returns a data reader (which should ideally be kept in a seperate DAL project, but you're not using code behind :() then have you're populate method like this

Code:
Sub populate()

ListBox1.DataSource = GetTemplates();
ListBox1.DataBind();

End Sub


Then have your control properties like this.


Code:
<asp:ListBox ID="ListBox1" DataTextField="category" DataValueField="templateId" runat="server" Width="200"></asp:ListBox>

You can keep you page load method the same


Code:
Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs)
    If Not Page.IsPostBack Then
       populate()
    End If
End Sub


You could try doing this for starters, but don't forget to update you're control properties with DataTextField="category" DataValueField="templateId" first.

Code:
Sub populate()
        Dim sqlStr As String = "SELECT templateId, category " & _
                               "FROM categories " & _
                               "WHERE templateId = @templateId"
        Dim sqlComm As SqlCommand = New SqlCommand(sqlStr, sqlConn)
        sqlComm.Parameters.Add(New SqlParameter("@templateId", SqlDbType.Int))
        sqlComm.Parameters("@templateId").Value = templateId
        Try
            sqlConn.Open()
            ListBox1.DataSource = sqlComm.ExecuteReader()
            ListBox1.DataBind
        Catch ex As Exception
            Response.Write(ex.Message)
        Finally
            sqlConn.Close()
        End Try
    End Sub

I use C# so some of the syntax might be wrong, but you get the general idea?
 
Last edited:
I've isolated the problem - it's something to do with one of the database columns I'm running the query on. This morning I tried the only thing left to try and I changed the actual columns being queried (just for the sheer hell of it).

The listbox now behaves correctly and remembers the item that was selected. Just need to find out what's causing the problem with the column I want to query now.

*Update*

No idea why it's doing this - it just doesn't seem to like me binding the templateId column to be the listbox VALUE property. It's fine if it's bound to the TEXT property (or not bound at all) but it just does not like being made to be a value and I've no idea why. The database field appears to be fine, just an int field with no anomalies, so I'm wondering if this is just a quirk.
 
Last edited:
Back
Top Bottom