asp.net中变量的值不变

时间:2013-04-23 19:20:28

标签: asp.net vb.net

目前我正在开展名为在线考试的项目。 所有控件都是动态创建的。

我有一个网页,我想显示学生的详细信息。 我在表格中正确显示了这些细节。 现在是编辑这些细节的时候了。 要编辑记录,我使用名为edit的链接按钮。 当用户单击该链接按钮时,该行中的数据将替换为新的文本框。 到此为止我很好。 现在,当我在更改文本框后单击“保存更改”按钮时。 旧值不会被新值替换,旧值仍然存在。

表格中创建文本框的代码如下:

Public Sub Edit_Click(ByVal sender As Object, ByVal e As System.EventArgs)

        For x As Integer = 0 To EditList.Count - 1

            If sender.id.substring(4) = EditList(x).ID.Substring(4) Then

                Session("PreviousRollNo") = RollNoList(x).Text

                Dim txtName As New TextBox
                txtName.Text = NameList(x).Text
                NameList(x).Text = ""
                NameList(x).Parent.Controls.Add(txtName)
                txtList.Add(txtName)

                Dim txtCourse As New TextBox
                txtCourse.Text = CourseList(x).Text
                CourseList(x).Text = ""
                CourseList(x).Parent.Controls.Add(txtCourse)
                txtList.Add(txtCourse)

                Dim txtAdmissionDate As New TextBox
                txtAdmissionDate.Text = AdmissionList(x).Text
                AdmissionList(x).Text = ""
                AdmissionList(x).Parent.Controls.Add(txtAdmissionDate)
                txtList.Add(txtAdmissionDate)

                Dim btnSaveChanges As New Button
                btnSaveChanges.Text = "Save Changes"
                EditList(x).Text = ""
                EditList(x).Parent.Controls.Add(btnSaveChanges)
                AddHandler btnSaveChanges.Click, AddressOf btnSaveChanges_Click
                Session("EditButtonClicked") = True

                Dim btnCancel As New Button
                btnCancel.Text = "Cancel"
                DeleteList(x).Text = ""
                DeleteList(x).Parent.Controls.Add(btnCancel)
                AddHandler btnCancel.Click, AddressOf btnCancel_Click
                Session("CancelButtonClicked") = True

                txtName.Focus()

                Exit For

            End If

        Next

    End Sub

“保存更改”按钮的代码如下:

Public Sub btnSaveChanges_Click(ByVal sender As Object, ByVal e As System.EventArgs)

        If txtList(0).Text = "" Then

            Dim trError As TableRow = New TableRow

            Dim tdError As TableCell = New TableCell
            tdError.ColumnSpan = 7

            Dim lblError As New Label
            lblError.Text = "Please enter name of the student."
            lblError.ForeColor = Drawing.Color.Red
            tdError.Controls.Add(lblError)

            trError.Controls.Add(tdError)

            tbl.Controls.Add(trError)

        ElseIf txtList(1).Text = "" Then

            Dim trError As TableRow = New TableRow

            Dim tdError As TableCell = New TableCell
            tdError.ColumnSpan = 7

            Dim lblError As New Label
            lblError.Text = "Please enter the course."
            lblError.ForeColor = Drawing.Color.Red
            tdError.Controls.Add(lblError)

            trError.Controls.Add(tdError)

            tbl.Controls.Add(trError)

        ElseIf txtList(2).Text = "" Then

            Dim trError As TableRow = New TableRow

            Dim tdError As TableCell = New TableCell
            tdError.ColumnSpan = 7

            Dim lblError As New Label
            lblError.Text = "Please enter the Admission Date"
            lblError.ForeColor = Drawing.Color.Red
            tdError.Controls.Add(lblError)

            trError.Controls.Add(tdError)

            tbl.Controls.Add(trError)

        Else

            Dim cb As New OleDbCommandBuilder(da)

            Dim editRow() As DataRow

            editRow = ds.Tables("Student_Detail").Select("Roll_No = '" & Session("PreviousRollNo") & "'")

            editRow(0)("Name") = txtList(0).Text
            editRow(0)("Course") = txtList(1).Text
            editRow(0)("Admission_Date") = txtList(2).Text

            da.Update(ds, "Student_Detail")

            Page.Response.Redirect("ChangeUserDetails.aspx")

        End If

    End Sub

我得到错误sying数组超出范围。在btnSaveChanges_Click的第一行。 这意味着当我单击Save Changes按钮时,txtlist总是被清除。 所以我将txtList存储在会话中,如Session(“txtList”)= txtList。 并从中检索数据。但是现在我得到了文本框的旧值而不是更新的值。 这里txtList是一个(文本框)列表

1 个答案:

答案 0 :(得分:3)

首先,欢迎来到ASP.NET WebForms Page Life Cycle。使用简单的助记符记住它的模式:SILVER = Start,Init,Load,Validate,Events,Render。

其次,HTTP是无状态WebForms做了一个惊人的工作,使用ViewState隐藏这个事实,直到你做了一些与众不同的事情(正如你现在正在尝试的那样),并且所有出现分崩离析。真正发生的事情是,您开始看到WebForms的管理方式的副作用,以及它与您可能认为的WinForms(或其他有状态系统)的不同之处。

当您在WebForms中回复事件服务器端时,很容易得到没有任何变化的印象。整个页面就像你“上次”离开它一样。所有控件都在那里,您可能以编程方式设置的值仍然设置。魔法。不是魔术。实际发生的是整个页面已被重新构建以响应该事件。它是如何重建的?通过组合页面定义(标记),控制事件处理程序中执行的操作以及客户端发回的form数据。

混淆?好的,让我们考虑一个例子。假设你有一个带有两个控件的页面。名为txtInput的文本框和名为btnSubmit的按钮,其中包含事件处理程序btnSubmit_Click。当用户首次请求页面时,这些控件的HTML将从您的标记(aspx页面)派生并返回给客户端。接下来,用户在txtInput中设置一个值,然后单击提交按钮。然后,服务器根据您的标记从头开始重新创建页面。在生命周期的早期阶段,控件仍然具有默认值。然后我们点击生命周期的Load阶段,“如果当前请求是回发,则控制属性加载从视图状态和控制状态恢复的信息。”在其他单词,当生命周期到达Init时,控件已经从标记创建,但仍然具有其默认值。然后Load阶段根据Postback数据设置值。

不知道这是如何适用于您的场景的?您正在添加动态控件以响应控件事件。这有两个问题:

  1. 在页面生命周期中Init基于从客户端发回的数据来设置值已经太晚了(回忆SILVEREvent 之后 em> Init)。
  2. 您的按钮点击事件处理程序仅运行一次,以响应用户点击按钮的回发。但请记住,每次回发都会重新创建页面 。因此,就服务器而言,动态控件不再存在!您会注意到,在响应提交事件时,不仅控件不在服务器端,而且在页面处理完之后,它们也不再存在于客户端。
  3. 那么答案是什么?那么我链接的页面的“生命周期事件”部分提供了一个线索。它声明PreInit事件用于(除此之外)“创建或重新创建动态控件”。我们为什么要在PreInit中执行此操作?所以它在页面生命周期中足够早,以便后期事件正确处理它(比如设置从客户端发回的值)。

    现在,我知道,您希望根据用户点击按钮添加控件。这怎么样?诀窍在于你必须自己管理“状态”。咦?国家?我的意思是MyDynamicControlsShouldBeShown = true / false。单击该按钮时,创建控件以响应按钮单击事件处理程序是正确的操作(那里没有任何选择)。但是你需要以某种方式存储该状态,以便在后续的页面请求中知道是否应该在PreInit中重新创建这些控件。一个简洁的选择是在Request.Form.Keys中检查动态控件的ID。如果控件ID出现在Keys集合中,则用户将回发控件的值,因此您应该重新创建它。


    关于使用Session

    的附注

    希望基于上述内容,您已经意识到为什么将控件放入Session不起作用。但要明确的是,您放入Session对象的控件不再是存在的页面的一部分(请记住,页面会为每个请求重新创建 。这些控件是不再与Page事件相关联,因此未在Page InitLoad之间填充其值。如果以某种方式 工作,它仍然不是一个特别好的主意,因为Session不是每个请求。那么如果用户在多个选项卡中打开相同的页面会发生什么?奇怪的事情,那是什么。