下拉列表选择值不变

dropdownlist selectedvalue doesnt change

我有这个下拉列表,它加载了我从存储过程中获取的数据,如您所见,加载是正确的,但是当我在调试中更改所选值时,所选值并没有改变,它停留在第一个加载的值,在本例中为 1。我能做什么?

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim adaptador As New SqlDataAdapter
    Dim datos As New DataTable
    Dim ord As SqlDataReader


    Conexiones.AbrirConexion()
    Conexiones.Cnn.Open()

    Dim cmd As SqlCommand = New SqlCommand("sp_devolver_empresas", Conexiones.Cnn)
    cmd.CommandType = CommandType.StoredProcedure

    ord = cmd.ExecuteReader

    datos.Load(ord)

    cbEmpresas.DataSource = datos
    cbEmpresas.DataTextField = "Nombre"
    cbEmpresas.DataValueField = "Identificador"
    cbEmpresas.DataBind()

    Conexiones.Cnn.Close()

End Sub

对于您构建并写入到时间结束的每个网页?

您必须始终将加载和设置代码放在 post 的检查中。

每个按钮、每个下拉列表以及每次您单击按钮或执行任何操作时,页面加载总是会触发并 运行。因此,如果您更改一个值,您将丢失该值,因为页面设置和加载 say 控件(在本例中为您的下拉列表)将触发每次 - 从而覆盖。

在最后 100 个网页中,我写的第一件事是检查 post返回。

因此,您的代码应如下所示:

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

    If Not IsPostBack Then
        LoadData
    End If

End Sub


Sub LoadData()
    Dim datos = New DataTable
    Using onexiones.Cnn
        Using cmd As SqlCommand = New SqlCommand("sp_devolver_empresas", onexiones.Cnn)
            cmd.CommandType = CommandType.StoredProcedure
            onexiones.Cnn.Open()
            datos.Load(cmd.ExecuteReader())
        End Using
    End Using

    cbEmpresas.DataTextField = "Nombre"
    cbEmpresas.DataValueField = "Identificador"
    cbEmpresas.DataSource = datos
    cbEmpresas.DataBind()

End Sub

所以,只有在“真正的”第一页加载时,您才想加载网格、下拉菜单等。请记住,即使是一个简单的按钮放到页面上,您也会有一个点击事件? (页面加载事件每次都会触发 - 并且每次都会触发)。所以再一次,你需要 IsPostBack 测试 - 我很想找到我的任何网页,这些网页在 on-load 事件中没有这些所有重要的代码存根。

因此,请记住上述规则 - 始终在第一次将设置代码设置为 运行 - 而不是每次在网页上出现按钮或其他任何内容时。因此,每次您在该页面上执行任何操作时都会触发页面加载(与桌面不同)。

另外,请注意在为下拉列表提供数据源之前我是如何设置数据文本和值字段的。事实上,我建议您将数据文本和数据值字段放在标记中而不是代码中(从那时起,多个不同的代码例程可以使用该设置 - 而不是硬编码在代码中)。

例如这样做:

    <asp:DropDownList ID="cbEmpresas" runat="server"
        DataTextField = "Nombre"
        DataValueField = "Identificador" >
    </asp:DropDownList>

所以,现在您的代码变为:

    cbEmpresas.DataSource = datos
    cbEmpresas.DataBind()

我认为有些人出于习惯喜欢在代码中为下拉列表设置文本 + 数据设置,但话又说回来,在代码中您可能需要多个位置来加载组合框 - 因此您现在这两个设置有多个位置。更好的是,您甚至可以在设计时使用 属性 sheet 进行设置。 (这是一个“小”问题,但我只是在标记中更喜欢这些设置,而不是在代码中为 text/data 设置编写它们)。

一天结束的时候?请记住这条黄金法则:对 post 进行“测试”,这样您就可以在 if/then 中获得真正的第一页加载事件代码。事实上,如果你违反这条规则,你甚至无法构建一个功能正常的网页。如前所述,我计算了 100 个网页中大约有 1-2 个没有 postback 代码存根。与人类必须呼吸空气才能发挥作用相比,它的重要性不言而喻。

为什么 post 这个简单的问题这么长?在几乎每天的基础上,c# 和 vb.net 问题都是关于某些组合框、网格视图或其他任何东西如何“损坏”且无法工作的问题。而答案是 10 次中的 9 次?

开发人员忘记在他们的页面加载代码中使用 Not IsPostBack 代码存根。

如果我在教 asp.net,这将是第一课 - 始终使用并考虑 Not IsPost 后存根的要求。您在 99% 的网页中都需要它。或者至少在任何网页中,您在页面加载时有代码 运行 以设置网格、下拉菜单、中继器 - 不管怎样,您都需要该代码存根。如此重要,我经常想知道他们是否应该创建一个名为 first page load 的事件?它会消除由于不注意上述简单建议而导致失败的每日 posts 和关于 SO 的问题。

编辑:现在如何在代码中获取选定值

好的,现在我们已经修复了设置下拉列表的代码,现在我们想在我们的代码中获取用户在下拉列表中进行选择时的值。

您当然有填充下拉菜单的代码,但我们还必须为此下拉菜单设置 autopostback = true。

那么,说出要加载的代码:

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

    If Not IsPostBack Then
        LoadData
    End If

End Sub


Sub LoadData()

    Using conn As New SqlConnection(My.Settings.TEST4)
        Dim strSQL As String =
            "SELECT ID, HotelName from tblHotels ORDER BY HotelName"

        Using cmdSQL As SqlCommand = New SqlCommand(strSQL, conn)
            conn.Open()
            Dim rstData As New DataTable
            rstData.Load(cmdSQL.ExecuteReader)
            cboHotels.DataSource = rstData
            cboHotels.DataBind()
        End Using

    End Using

End Sub

现在选择的索引更改事件:

因此,我们的调试输出将如下所示:

输出:

combo selected value = 82
combo selected Text = Canadian Rocky Mountain Resorts

并且如前所述,请确保在 属性 sheet 或标记中将 auto-post 设置回 true。因此,上面标记中的组合框是这样的:

    <asp:DropDownList ID="cboHotels" runat="server"
        DataValueField="ID"
        DataTextField="HotelName" AutoPostBack="True">
    </asp:DropDownList>