以下文章來自於「章立民」老師的文章

http://blog.xuite.net/alwaysfuturevision/liminzhang/11832570

問題

老師你好, 關於 Ajax 是否實現以下功能

我把PlaceHolder1放在UpdataPanel,想要動態增加TextBox放在PlaceHolder1裡頭;然後使用者輸入相關資訊,我也能讀到textbox的值.  接這使用者又按下"新增產生TextBox 放在PlaceHolder1,而之前在PlaceHolder1 鍵入的值 也完全保留~一直循這樣的動作 直到完成.  我試過很多遍,似乎Ajax "局部更新"還是無法達到類似功能.

不知道是原本就不能,還是有何小技巧呢?  thanks 忠實的讀者

解答

大家都知道,正由於網頁是無狀態的(Stateless),因此 ASP.NET 特別提供狀態管理(ViewState),以便網頁開發人員得以追蹤使用者的 UI 狀態。說穿了,這也不是什麼新技術,只不過利用隱藏的表單欄位來保存狀態。因此,我們將使用狀態管理來維護這些動態加入的控制項之狀態。

如圖表 所示,是網頁程式第一次執行的畫面,我們可以看到,網頁程式會建立一個具備  ASP.NET AJAX Control Toolkit 浮水印文字方塊(TextBoxWatermark)功能的  TextBox  控制項,並於網頁的最一列與最後一列,顯示相關事件的時間。

 




 

每按下一次「新增 TextBox按鈕,便會自動加入一個新的 TextBox 控制項。當然,新加入的 TextBox 控制項也已經與ASP.NET AJAX Control Toolkit 浮水印文字方塊(TextBoxWatermark建立關聯。於各個 TextBox 控制項中,輸入適當的資料,並按下「送出」按鈕之後,便可以看到網頁以非同步的方式,取得各個 TextBox 控制項的資料,並顯示在網頁上(如圖表2、圖表3所示)。

如圖表4所示者,是網頁的設計畫面。在頁面中,我們將 PlaceHolder 控制項放置於 UpdatePanel 控制項中,並將 UpdateMode設定為 Conditional,以便當按下「新增 TextBox「送出」按鈕時,網頁以非同步方式局部更新該 UpdatePanel 控制項中的內容,也就是說,此舉得以讓 PlaceHolder 控制項中的內容被更新。

 

網頁的程式碼後置(Code-Behind)內容如下所列:


Option Strict On
' 匯入浮水印文字方塊(TextBoxWatermark)所需的命名空間。
Imports AjaxControlToolkit

Partial Class _Default
  Inherits System.Web.UI.Page

  ' 使用 HTML 的<br>標籤來斷行。
  Private br As LiteralControl = New LiteralControl("<br />")

  ' 使用 HTML 的<hr>標籤來分隔。
  Private hr As LiteralControl = New LiteralControl("<hr />")

  Protected Sub Page_Load(ByVal sender As Object, _
    ByVal e As System.EventArgs) _
    Handles Me.Load
    ' 檢查是否為 PostBack。
    If IsPostBack Then
      Label1.Text = "由 PostBack 觸發的,於 " & Now.ToString()
      If ViewState("Mode").ToString() = "Add" AndAlso _
        ViewState("ControlsAdded") Is Nothing Then
        ' 動態加入網頁初始時,所需的控制項。
        AddControls()
      End If

      ' 動態加入 TextBox 控制項。
      If (CInt(ViewState("TextBoxID")) > 0) Then
        For intLoop As Integer = 1 To CInt(ViewState("TextBoxID"))
          AddNewTextBox(intLoop.ToString())
        Next
      End If
    Else
      Label1.Text = "非 PostBack 觸發的,於 " & Now.ToString()
      ViewState("Mode") = "Init"
      AddControls()
    End If
  End Sub

  ' 覆寫載入狀態的動作,以便管理狀態。
  Protected Overrides Sub LoadViewState(ByVal savedState As Object)
    MyBase.LoadViewState(savedState)
    If CType(ViewState("ControlsAdded"), Boolean) = True Then
      AddControls()
    End If
  End Sub

  ' 建立網頁初始時的控制項。
  Private Sub AddControls()
    ' 建立 TextBox 控制項。
    Dim tb As New TextBox()
    tb.ID = "TB_0"
    tb.CssClass = "cssTextBox"

    ' 建立浮水印文字方塊。
    Dim tbwe As New TextBoxWatermarkExtender()
    tbwe.ID = "TBWE_0"
    tbwe.TargetControlID = "TB_0"
    tbwe.WatermarkText = "請輸入資料...(0)"
    tbwe.WatermarkCssClass = "cssWatermark"

    ' 建立「新增 TextBox」按鈕。
    Dim btnAdd As New Button()
    btnAdd.Text = "新增 TextBox"
    btnAdd.ID = "AddButton"
    btnAdd.Font.Bold = True
    btnAdd.BackColor = Drawing.Color.Blue
    btnAdd.ForeColor = Drawing.Color.White

    ' 指派「新增 TextBox」按鈕的 Click 事件處理常式。
    AddHandler btnAdd.Click, AddressOf btnAdd_Click

    ' 建立「送出」按鈕。
    Dim btnSend As New Button()
    btnSend.Text = "送出"
    btnSend.ID = "SendButton"
    btnSend.Font.Bold = True
    btnSend.BackColor = Drawing.Color.Yellow
    btnSend.ForeColor = Drawing.Color.Black

    ' 指派「送出」按鈕的 Click 事件處理常式。
    AddHandler btnSend.Click, AddressOf btnSend_Click

    ' 將所建立的控制項加至 PlaceHolder 控制項裡。
    PlaceHolder1.Controls.Add(tb)
    PlaceHolder1.Controls.Add(tbwe)
    PlaceHolder1.Controls.Add(hr)
    PlaceHolder1.Controls.Add(btnAdd)

    ' 插入空白字元,以免兩個按鈕相連在一起。
    For i As Integer = 1 To 10
      PlaceHolder1.Controls.Add(New LiteralControl(" "))
    Next

    PlaceHolder1.Controls.Add(btnSend)
    PlaceHolder1.Controls.Add(br)

    ' 確認已經動態加入控制項。
    ViewState("ControlsAdded") = True
  End Sub

  ' 建立 TextBox 控制項。
  Private Sub AddNewTextBox(ByVal ControlID As String)
    Dim tb As New TextBox()
    tb.ID = "TB_" & ControlID

    ' 建立 AJAX Control Toolkit 浮水印文字方塊(TextBoxWatermark)。
    Dim tbwe As New TextBoxWatermarkExtender()
    tbwe.ID = "TBWE_" & ControlID
    tbwe.TargetControlID = "TB_" & ControlID
    tbwe.WatermarkText = "請輸入資料...(" & ControlID & ")"
    tbwe.WatermarkCssClass = "cssWatermark"

    ' 將 TextBox 加入特定的位置上。
    PlaceHolder1.Controls.AddAt(CInt(ControlID), tb)
    PlaceHolder1.Controls.Add(tbwe)
  End Sub

  ' 「新增 TextBox」按鈕的 Click 事件處理常式。
  Protected Sub btnAdd_Click(ByVal sender As Object, _
    ByVal e As System.EventArgs)
    ' 指定所按下的按鈕模式。
    ViewState("Mode") = "Add"

    ' 為了避免 TextBox ID 相同,使用 ViewState 來記錄目前的 TextBox ID。
    If ViewState("TextBoxID") Is Nothing Then
      ViewState("TextBoxID") = 1
    Else
      ' 刻意使用 ViewState 的 Add 方法。
      ViewState.Add("TextBoxID", CInt(ViewState("TextBoxID")) + 1)
    End If

    AddNewTextBox(ViewState("TextBoxID").ToString())
  End Sub

  ' 「送出」按鈕的 Click 事件處理常式。
  Protected Sub btnSend_Click(ByVal sender As Object, _
    ByVal e As System.EventArgs)
    ' 指定所按下的按鈕模式。
    ViewState("Mode") = "Send"

    Const hrColor As String = _
      "<hr width='300px' color='cyan' align='left' size='5' />"

    ' 建立 Label 控制項,以便顯示於 TextBox 所輸入的資料。
    Dim lbl As New Label()
    lbl.ID = "lblResult"
    lbl.Text = "<br />" & hrColor

    ' 取得每個按鈕的內容。
    Dim tb As New TextBox()
    For intLoop As Integer = 0 To CInt(ViewState("TextBoxID"))
      tb = CType(PlaceHolder1.FindControl("TB_" & intLoop), TextBox)
      lbl.Text &= tb.ID & " 的內容為:" & tb.Text & "<br />"
    Next

    lbl.Text &= hrColor & "<br />"

    PlaceHolder1.Controls.Add(lbl)
  End Sub
End Class
arrow
arrow
    全站熱搜

    kingjoy1235 發表在 痞客邦 留言(0) 人氣()