保存动态创建的文本框的值

时间:2014-12-30 00:04:21

标签: asp.net vb.net postback dynamically-generated

更新1:我正在调查此链接。 Retaining dynamically created controls during PostBack - VB.net 它可能解释了我需要知道的事情。上述链接中的注释提到使用相同的ID重新创建控件。 ASP.net会自动保留该值。然后,我将能够找到控件并获取键入的值。 ..谢谢..

UPDATE2:感谢Win的评论以及上面的链接,我想我想出来了。稍后会确认并发布回复。

我必须道歉,似乎有一千个类似的问题。但在阅读了许多问题和答案后,我仍然无法使我的简单页面正常工作。我很陌生。请允许我再问这个问题。

我有一个非常简单的ASPX页面,带有一个下拉列表,一个表和一个按钮。 使用datatable(datatable来自SQL表)填充下拉列表。该表用于动态创建的文本框的容器。和一个按钮来进行更新。 下面是我在ASPX和vb.net代码背后的代码片段

我遇到的问题是page.findcontrol无法找到动态创建的控件。我隐约明白这是一个问题,因为回帖,page_load vs page_init。但在我读完的所有教程之后,我仍然没有完全理解:( ..你可以帮助如何使这项工作?

非常感谢你

额外信息: 无论如何,我尝试做了在coment中建议的内容,并且我在页面加载或init上重新创建控件,但是当我创建它时,文本框中会有什么值?这是用户看到的流程。

  1. step0第一次加载页面时,还没有动态文本框
  2. Step1用户选择值34
  3. step2 autopostback selectedindexchanged fired和34传递 回到服务器并返回2个名字joe和jack,它创建 带有joe的动态textbox_1和带有jack的动态textbox_2。
  4. Step3用户在textbox_1中键入值jane。和 点击button1。
  5. Step4 button1单击事件已触发,我正在尝试捕获该单词 jane in textbox_1但我不能。因为我找不到控制权 textbox_1由于时间或我的知识有限。这是我的地方 需要一些帮助。
  6. ASPX

    <body>
        <form id="form1" runat="server">
        <div>
    
            <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True">
            </asp:DropDownList>
            <br />
            <br />
            <asp:Table ID="Table1" runat="server">
            </asp:Table>
            <br />
            <asp:Button ID="Button1" runat="server" Text="Button" />
    
        </div>
        </form>
    </body>
    

    VB.net

    Imports System.Data.SqlClient
    Public Class DynamicControl
        Inherits System.Web.UI.Page
        Dim connString As String = "Server=Local;Database=SampleData;Trusted_Connection=True;Max Pool Size=1000"
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Not IsPostBack Then
                getData()
            End If
        End Sub
        Private Sub getData()
            Dim dt As New DataTable
            Dim SQLString As String
            Dim conn As New SqlConnection
            conn.ConnectionString = connString
            conn.Open()
            SQLString = "select DepartmentID from Employee where departmentid is not null group by departmentid"
            getDataBySQLConn(SQLString, dt, conn)
            DropDownList1.DataSource = dt
            DropDownList1.DataValueField = "DepartmentID"
            DropDownList1.DataTextField = "DepartmentID"
            DropDownList1.DataBind()
        End Sub
        Protected Sub DropDownList1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles DropDownList1.SelectedIndexChanged
            Dim dt As New DataTable
            Dim SQLString As String
            Dim conn As New SqlConnection
            conn.ConnectionString = connString
            conn.Open()
            SQLString = "select employeeid,lastname from Employee where departmentid =" & DropDownList1.SelectedValue.ToString
            getDataBySQLConn(SQLString, dt, conn)
            For Each rows As DataRow In dt.Rows
                Dim tTextBox As New TextBox
                Dim tr As New TableRow
                Dim tc As New TableCell
                tTextBox.ID = "txtEmployee_" & rows("EmployeeID")
                tTextBox.Text = rows("lastname")
                tr.Cells.Add(tc)
                tc.Controls.Add(tTextBox)
                Table1.Rows.Add(tr)
            Next
        End Sub
        Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'Update Employee set lastname = '' where employeeID = 2
            Dim iEmployeeID As Integer
            Dim sLastName As String
            Dim tTextBox As TextBox
            iEmployeeID = DirectCast(Page.FindControl("txtEmployee_1"), TextBox).ToString
            tTextBox = Page.FindControl("txtEmployee_1")
            sLastName = tTextBox.Text
        End Sub
    End Class
    

    注意:button1单击事件未完成。但是一旦我弄清楚如何捕获文本框中输入的数据,我就可以完成其余的工作。我的主要问题是我无法获取txtEmployee_1的值,也无法找到控件。我似乎在错误的时间使用了findcontrol,或者在错误的时间初始化了控件。

    这是我的表

    ╔════════════╦══════════════╦════════════╗
    ║  LastName  ║ DepartmentID ║ EmployeeID ║
    ╠════════════╬══════════════╬════════════╣
    ║ Rafferty   ║           31 ║          1 ║
    ║ Jones      ║           33 ║          2 ║
    ║ Heisenberg ║           33 ║          3 ║
    ║ Robinson   ║           34 ║          4 ║
    ║ Smith      ║           34 ║          5 ║
    ╚════════════╩══════════════╩════════════╝
    

2 个答案:

答案 0 :(得分:0)

我在我正在处理的应用程序中做了类似的事情。让我举一个非常简单的例子,我认为这会有所帮助:

<强> Default.aspx的:

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="WebApplication3._Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Button ID="Button1" runat="server" Text="Make textbox" />
        <asp:Button ID="Button2" runat="server" Text="Get textbox text" />
    </div>
    </form>
</body>
</html>

<强> Default.aspx.vb:

Public Class _Default
    Inherits System.Web.UI.Page

    Protected controlBag As New Dictionary(Of String, Control)
    Protected Const textBox1Name As String = "textBox1"
    Protected Const textBox1EnabledName As String = "textBox1Status"

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If ViewState(textBox1EnabledName) = True Then
            makeTextBox()
        End If
    End Sub

    Private Sub makeTextBox()
        Dim x As New TextBox
        x.ID = textBox1Name
        If Not controlBag.ContainsKey(textBox1Name) Then
            form1.Controls.Add(x)
            controlBag.Add(x.ID, x)
        End If
    End Sub

    Private Sub removeTextBox()
        If controlBag.ContainsKey(textBox1Name) Then
            form1.Controls.Remove(controlBag(textBox1Name))
        End If
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ViewState(textBox1EnabledName) = True
        makeTextBox()
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Dim x As New Literal

        If controlBag.ContainsKey(textBox1Name) Then
            x.Text = String.Format("Here's the text: {0}", DirectCast(controlBag(textBox1Name), TextBox).Text)
            removeTextBox()

            ViewState(textBox1EnabledName) = False
        Else
            x.Text = "The textbox does not exist"
        End If

        form1.Controls.Add(x)
    End Sub
End Class

一般想法:

  1. 构建动态控件。将它们添加到页面,但也将它们添加到字典中。我使用Dictionary(Of String,Control)。这有助于以后查找其数据。您需要在何时创建控件以及绑定它们的内容上添加逻辑。
  2. 在回发时,您必须重新创建完全相同的控件,即使您不希望它们出现在最终页面输出上。您必须在访问其数据之前执行此操作。将它们添加到页面控件集合中,不要忘记将它们添加到字典中。
  3. 使用您的字典和控件ID的名称进行查找,并将其直接转换为所需的控件类型。
  4. 对控件中的数据执行任何操作。您提到了文本框,因此您将使用已转换控件的.Text属性。
  5. 如果您已完成控件,则可以从页面控件集合中删除它。更新您用于不再创建文本框的逻辑。

答案 1 :(得分:0)

我使用

解决了这个问题
For Each s As String In Request.Params

而不是

DirectCast(Page.FindControl("txtEmployee_1"), TextBox).ToString

使用Request.Params我能够捕获用户键入的内容

For Each s As String In Request.Params
  If s.contains(txtEmployee_1) THEN txtUserTyped = Request(s)
Next