目前我正在开展名为在线考试的项目。 所有控件都是动态创建的。
我有一个网页,我想显示学生的详细信息。 我在表格中正确显示了这些细节。 现在是编辑这些细节的时候了。 要编辑记录,我使用名为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是一个(文本框)列表
答案 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数据设置值。
不知道这是如何适用于您的场景的?您正在添加动态控件以响应控件事件。这有两个问题:
Init
基于从客户端发回的数据来设置值已经太晚了(回忆SILVER
,Event
之后> em> Init
)。那么答案是什么?那么我链接的页面的“生命周期事件”部分提供了一个线索。它声明PreInit
事件用于(除此之外)“创建或重新创建动态控件”。我们为什么要在PreInit
中执行此操作?所以它在页面生命周期中足够早,以便后期事件正确处理它(比如设置从客户端发回的值)。
现在,我知道,您希望根据用户点击按钮添加控件。这怎么样?诀窍在于你必须自己管理“状态”。咦?国家?我的意思是MyDynamicControlsShouldBeShown
= true / false。单击该按钮时,创建控件以响应按钮单击事件处理程序是正确的操作(那里没有任何选择)。但是你需要以某种方式存储该状态,以便在后续的页面请求中知道是否应该在PreInit
中重新创建这些控件。一个简洁的选择是在Request.Form.Keys
中检查动态控件的ID。如果控件ID出现在Keys
集合中,则用户将回发控件的值,因此您应该重新创建它。
希望基于上述内容,您已经意识到为什么将控件放入Session
不起作用。但要明确的是,您放入Session
对象的控件不再是存在的页面的一部分(请记住,页面会为每个请求重新创建 。这些控件是不再与Page
事件相关联,因此未在Page
Init
和Load
之间填充其值。如果以某种方式 工作,它仍然不是一个特别好的主意,因为Session
不是每个请求。那么如果用户在多个选项卡中打开相同的页面会发生什么?奇怪的事情,那是什么。