locked
Dropdown SelectedIndexChanged event doesn't know selected value when called from another function RRS feed

  • Question

  • User673640389 posted

    My form has an asp dropdownlist that is populated from a sqldatasource.  It has an "selectedindexchanged" event that populates another dropdown list based on the value selected in the first dropdown.  That works all fine and dandy.

    However, in the page load event, I'm evaluating url parameters.  The URL parameters populate various fields, including this dropdownlist.  From the page load event, I call the selectedindexchanged event.   But when that event is called from the page load event, the dropdown lists "selectedvalue" is null...even though the dropdown list appears to have been set correctly based on the URL parameter. So the end result, is that my 2nd dropdown list does not populate with the first one is populated by a URL parameter.

    I used a "message box" to display the value of the first drop down in the selectedindexchange method, which is how I know the backend does not know the value of the dropdown when it's populated by the URL parameter and run from the page load event.

    Code (with some things masked out):

    Protected Sub Exception_dl_SelectedIndexChanged(sender As Object, e As EventArgs)

    Dim sqldatasource_reason As New SqlDataSource
    reason_dl.DataSource = sqldatasource_reason
    reason_dl.DataTextField = "description"
    reason_dl.DataValueField = "ID"

    sqldatasource_reason.ConnectionString = connectionstring_transbsddb

    sqldatasource_reason.SelectParameters.Add("exceptionid", exception_dl.SelectedValue)
    sqldatasource_reason.SelectCommand = "Select ID, Description FROM ***** where id In (Select reasonid from **** where Active='Y' and exceptionid = @exceptionid) "

    reason_dl.DataBind()
    end sub

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load


    empid = Request.QueryString("empid")
    If empid <> "" Then
    empid_txt.Text = empid
    End If

    exceptiontype = Request.QueryString("extype")
    If exceptiontype >= 1 Then
    exception_dl.SelectedIndex = exceptiontype
    End If

    exceptiondate = Request.QueryString("exdate")
    If exceptiondate <> "" Then
    exceptiondate_txt.Value = exceptiondate
    End If


    Exception_dl_SelectedIndexChanged(New Object(), New EventArgs())


    End Sub

    Thursday, December 20, 2018 9:05 PM

Answers

  • User-1174608757 posted

    Hi AaronR_

    According to your description,I have made a sample here. I guess that you bind  exception_dl in aspx such as using sqldatasource control but not in code behind .The key to your issue is that the bind event of exception_dl happened after page_load event
    If you just bind exception_dl in aspx ,the reason_dl couldn't directly get the selected value of exception_dl in code behind when first load the page.
    Similarly, the selected index of exception_dl  shows -1 means the value is null.It can't get the value.since it hasn't bound the data in  page_load.

    Here are two demos about the situations.I hope it can help you.

    (Bind in aspx)dropdownlist.aspx:

    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:DropDownList ID="D1" runat="server" OnSelectedIndexChanged="D1_SelectedIndexChanged"
                    AutoPostBack="True" DataSourceID="SqlDataSource1" DataTextField="fruit" DataValueField="fruit" >
                                  
                </asp:DropDownList>
                <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:mssqlserver %>" SelectCommand="SELECT [fruit] FROM [db]"></asp:SqlDataSource>
                <asp:DropDownList ID="D2" runat="server"></asp:DropDownList>
            </div>
        </form>
    </body>

    dropdownlist.aspx.vb:

    Public Class dropdownlist
        Inherits System.Web.UI.Page
        Public Shared Function ExecuteDataTable(ByVal sql As String, ParamArray pms As SqlParameter()) As DataTable
            Dim conStr As String = ConfigurationManager.ConnectionStrings("mssqlserver").ConnectionString
            Dim dt As DataTable = New DataTable()
    
            Using adapter As SqlDataAdapter = New SqlDataAdapter(sql, conStr)
    
                If pms IsNot Nothing Then
                    adapter.SelectCommand.Parameters.AddRange(pms)
                End If
                adapter.Fill(dt)
            End Using
    
            Return dt
        End Function
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Not IsPostBack Then
                D1.SelectedIndex = 1
                Response.Write(D1.SelectedIndex)
                D1_SelectedIndexChanged(New Object, New EventArgs)
            End If
        End Sub
        Protected Sub D1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
            Dim s As String = D1.SelectedValue
    
            Dim sql As String = "select color from db where fruit=@fruit"
            D2.DataSource = ExecuteDataTable(sql, New SqlParameter("@fruit", s))
            D2.DataValueField = "color"
            D2.DataBind()
        End Sub
    
    End Class

    It shows as below:

    (Bind in code behind)dropdownlist.aspx:

    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:DropDownList ID="D1" runat="server" OnSelectedIndexChanged="D1_SelectedIndexChanged" AutoPostBack="true"></asp:DropDownList>
                <asp:DropDownList ID="D2" runat="server"></asp:DropDownList>
            </div>
        </form>
    </body>

    aspx.vb:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Not IsPostBack Then
                Dim sql As String = "select fruit from db "
                D1.DataSource = ExecuteDataTable(sql)
                D1.DataValueField = "fruit"
                D1.DataBind()
                D1.SelectedIndex = 1
                Response.Write(D1.SelectedIndex)
                D1_SelectedIndexChanged(New Object, New EventArgs)
            End If
        End Sub
        Protected Sub D1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
            Dim s As String = D1.SelectedValue
            Dim sql As String = "select color from db where fruit=@fruit"
            D2.DataSource = ExecuteDataTable(sql, New SqlParameter("@fruit", s))
            D2.DataValueField = "color"
            D2.DataBind()
        End Sub

    It shows:

    Best Regards

    Wei Zhang

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, December 21, 2018 8:09 AM

All replies

  • User673640389 posted

    I think I"m running into some kind of order of operations issue.

    In the page load event, I set the selected index value of the drop down to 1, and the dropdown shows the correct associated text value.  Then I put a MessageBox.Show(exception_dl.SelectedIndex) after that, and it say it reports -1.  

    When I run this code, the message box actually appears first showing a value of -1, then the dropdown list index gets set to 1.    So the bolded line is setting the selected index value to 1, and the next line which should be showing the newly set index of 1 is instead showing -1.  Which would explain why the code that is supposed to set the 2nd box doesn't work.

    If exceptiontype >= 1 Then
    exception_dl.SelectedIndex = exceptiontype     <----sets value to 1
    MessageBox.Show(exception_dl.SelectedIndex)        <----shows -1

    End if

    Thursday, December 20, 2018 10:36 PM
  • User-1174608757 posted

    Hi AaronR_

    According to your description,I have made a sample here. I guess that you bind  exception_dl in aspx such as using sqldatasource control but not in code behind .The key to your issue is that the bind event of exception_dl happened after page_load event
    If you just bind exception_dl in aspx ,the reason_dl couldn't directly get the selected value of exception_dl in code behind when first load the page.
    Similarly, the selected index of exception_dl  shows -1 means the value is null.It can't get the value.since it hasn't bound the data in  page_load.

    Here are two demos about the situations.I hope it can help you.

    (Bind in aspx)dropdownlist.aspx:

    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:DropDownList ID="D1" runat="server" OnSelectedIndexChanged="D1_SelectedIndexChanged"
                    AutoPostBack="True" DataSourceID="SqlDataSource1" DataTextField="fruit" DataValueField="fruit" >
                                  
                </asp:DropDownList>
                <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:mssqlserver %>" SelectCommand="SELECT [fruit] FROM [db]"></asp:SqlDataSource>
                <asp:DropDownList ID="D2" runat="server"></asp:DropDownList>
            </div>
        </form>
    </body>

    dropdownlist.aspx.vb:

    Public Class dropdownlist
        Inherits System.Web.UI.Page
        Public Shared Function ExecuteDataTable(ByVal sql As String, ParamArray pms As SqlParameter()) As DataTable
            Dim conStr As String = ConfigurationManager.ConnectionStrings("mssqlserver").ConnectionString
            Dim dt As DataTable = New DataTable()
    
            Using adapter As SqlDataAdapter = New SqlDataAdapter(sql, conStr)
    
                If pms IsNot Nothing Then
                    adapter.SelectCommand.Parameters.AddRange(pms)
                End If
                adapter.Fill(dt)
            End Using
    
            Return dt
        End Function
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Not IsPostBack Then
                D1.SelectedIndex = 1
                Response.Write(D1.SelectedIndex)
                D1_SelectedIndexChanged(New Object, New EventArgs)
            End If
        End Sub
        Protected Sub D1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
            Dim s As String = D1.SelectedValue
    
            Dim sql As String = "select color from db where fruit=@fruit"
            D2.DataSource = ExecuteDataTable(sql, New SqlParameter("@fruit", s))
            D2.DataValueField = "color"
            D2.DataBind()
        End Sub
    
    End Class

    It shows as below:

    (Bind in code behind)dropdownlist.aspx:

    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:DropDownList ID="D1" runat="server" OnSelectedIndexChanged="D1_SelectedIndexChanged" AutoPostBack="true"></asp:DropDownList>
                <asp:DropDownList ID="D2" runat="server"></asp:DropDownList>
            </div>
        </form>
    </body>

    aspx.vb:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Not IsPostBack Then
                Dim sql As String = "select fruit from db "
                D1.DataSource = ExecuteDataTable(sql)
                D1.DataValueField = "fruit"
                D1.DataBind()
                D1.SelectedIndex = 1
                Response.Write(D1.SelectedIndex)
                D1_SelectedIndexChanged(New Object, New EventArgs)
            End If
        End Sub
        Protected Sub D1_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
            Dim s As String = D1.SelectedValue
            Dim sql As String = "select color from db where fruit=@fruit"
            D2.DataSource = ExecuteDataTable(sql, New SqlParameter("@fruit", s))
            D2.DataValueField = "color"
            D2.DataBind()
        End Sub

    It shows:

    Best Regards

    Wei Zhang

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, December 21, 2018 8:09 AM
  • User673640389 posted

    You are brilliant!  Thank you!  I remember debating whether or not to use a sql data source in the aspx or code behind, and couldn't figure why it would make a dif (I'm new to making web apps).

    Thursday, January 3, 2019 7:06 PM