[ASP.NET][WebForm]用Table控制項,動態產生陣列型TextBox,並且取得使用者輸入的資料

剛好遇見網友在詢問一個問題,他需要『動態產生陣列型的TextBox,讓使用者輸入資料,並且輸入後,按下送出,可以將使用者輸入的內容讀出。』。這要如何處理?小喵來撰寫這樣的一個範例。順便說明動態產生控制項的一些處理概念。

緣起:

一個偶然的機會,看到網友在FB中詢問有關動態產生控制項的問題,小喵用這個範例來做個簡單的說明。

一些觀念的共享:

動態產生控制項,小喵自己在撰寫時,能避免就避免,因為這樣的程式碼通常不容易維護,不過有時候不得不的時候,我們還是需要知道一些動態產生控制項的幾個觀念。

如何保留狀態:

Web是沒有狀態的,為了保留狀態,在WebForm中,會藉助於『ViewState』來協助保留狀態。然而,動態產生控制項,產生了,如何保留這些控制項,還有控制項的狀態。最簡單的方式,就是把動態產生控制項的動作,寫在Page的Init事件。

Page_Init事件如何取得畫面控制項的內容

在Page的Init事件中,畫面中的其他控制項都還沒有準備好,所以如果用Me.TextBox1.Text,會取不到該物件。如果要取得的資料是畫面中PostBack送出的,那麼,取資料的方式,要回歸到最原始的『Request.Form』的方式來取得。

範例:

有了以上的概念後,我們就來撰寫這次的範例,這次的範例,希望的是在畫面中,安排兩個TextBox,分別輸入我們要產生橫向(X)與縱向(Y)的個數。
PostBack後,如果資料與上次的X,Y不同,會重新再次產生依據X,Y的數字,產生陣列型的TextBox在Table1控制項中(如果相同,就不再重新產生)

另外,會在畫面中,安排一個Table控制項,由此Table控制項來放動態產生的TextBox
會再安排一個按鈕,用來取得使用者輸入的內容。

大概預期產生的畫面如下:

接下來,就來看Code:

aspx:

x:<asp:TextBox ID="txtX" runat="server"></asp:TextBox><br />
y:<asp:TextBox ID="txtY" runat="server"></asp:TextBox><br />
<asp:Button ID="btnGenArrayList" runat="server" Text="產生" />
<hr />
<asp:Table ID="Table1" runat="server" BorderStyle="Solid">
</asp:Table>
<br />
<asp:Button ID="btnGetDatas" runat="server" Text="取得資料" style="margin-bottom: 0px" />
<hr />
<asp:Label ID="lblRlt" runat="server" Text=""></asp:Label>

CodeFile(aspx.vb):

    Private Sub tDynamicArrayListGV_Init(sender As Object, e As EventArgs) Handles Me.Init
        If IsPostBack Then
            Dim ReGen As Boolean = False
            Dim X As Integer = 0
            If IsNumeric(Request.Form("txtX")) Then
                X = CInt(Request.Form("txtX"))
                If X <> ViewState("X") Then
                    ReGen = True
                    ViewState("X") = X
                End If

            End If
            Dim Y As Integer = 0
            If IsNumeric(Request.Form("txtY")) Then
                Y = CInt(Request.Form("txtY"))
                If Y <> ViewState("Y") Then
                    ReGen = True
                    ViewState("Y") = Y
                End If
            End If
            If ReGen And X > 0 And Y > 0 Then
                Dim tCell As TableCell
                Dim tRow As TableRow
                Dim tTxt As TextBox
                For y1 = 1 To Y
                    tRow = New TableRow()
                    For x1 = 1 To X
                        tCell = New TableCell
                        tTxt = New TextBox()
                        tTxt.ID = "txt_" & x1.ToString & "_" & y1.ToString
                        tTxt.Text = "txt_" & x1.ToString & "_" & y1.ToString
                        tCell.Controls.Add(tTxt)
                        tRow.Cells.Add(tCell)
                    Next
                    Me.Table1.Rows.Add(tRow)
                Next
            End If
        End If
    End Sub

    Protected Sub btnGetDatas_Click(sender As Object, e As EventArgs) Handles btnGetDatas.Click
        Dim X As Integer = ViewState("X")
        Dim Y As Integer = ViewState("Y")

        Dim Rlt As String = ""
        Dim tTxt As TextBox
        For y1 = 1 To Y
            For x1 = 1 To X
                tTxt = CType(Me.Table1.FindControl("txt_" & x1.ToString & "_" & y1.ToString), TextBox)
                If tTxt IsNot Nothing Then
                    Rlt &= tTxt.Text & ","
                End If
            Next
            Rlt = Mid(Rlt, 1, Len(Rlt) - 1) & "<br/>"
        Next
        Me.lblRlt.Text = Rlt
    End Sub

後記:

最後整理一次重點:

  1. 寫在Page_Init事件中:
    動態產生控制項,重點在於要把產生控制項的過程,寫在Page_Init事件中,這樣ViewState的作用就自然而生,不必特別為了保留這些動態產生控制項的狀態,特別寫什麼。
  2. Page_Init中,用Request.Form取得送過來資料:
    不過由於寫在Page_Init事件中,無法用『Me.TextBox1.Text』取得畫面輸入的內容,所以要改由『Request.Form』來取得。

以上的範例,提供大家參考。

 

 

 

 


以下是簽名:


Microsoft MVP
Visual Studio and Development Technologies
(2005~2019/6)