2013-07-11 60 views
27

實際上,我正在創建TextBox,Pageload並將TextBox添加到Panel。 現在,我有一個LinkButtonAdd Another動態創建控件在回發後丟失數據

我在TextBox中輸入文本,如果需要,我需要創建新的TextBox,點擊Add Another LinkButton

其實,我能夠得到計數並重新創建TextBoxes。 但問題在於,以前生成的Textboxes中的我的輸入文本缺失。

任何人都可以,建議我一個解決方案?

protected void Page_Load(object sender, EventArgs e) 
    { 
     try 
     { 
      if (!IsPostBack) 
      { 
       for (int i = 0; i < 5; i++) 
       { 
        TableRow row = new TableRow(); 
        for (int j = 0; j < 5; j++) 
        { 
         TableCell cell = new TableCell(); 
         TextBox tb = new TextBox();       
         tb.ID = "TextBoxRow_" + i + "Col_" + j;       
         cell.Controls.Add(tb);       
         row.Cells.Add(cell); 
        }      
        Table1.Rows.Add(row); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      throw; 
     }   
    } 

這是一個示例代碼,同樣的代碼寫在Button_Click

protected void ASPxButton1_Click(object sender, EventArgs e) 
    { 
int k = Table1.Controls.Count; 
} 

我得到一個Count=0Button_Click我。

+1

你能告訴我們一些代碼嗎? –

回答

3

這是我的工作很多具有動態後,最終的答案控制

的.aspx

<form id="form1" runat="server"> 
<asp:ScriptManager ID="ScriptManager1" runat="server"> 
</asp:ScriptManager> 
<div style="text-align: center"> 
    <div style="background-color: Aqua; width: 250px;"> 
    <br /> 
    <asp:UpdatePanel ID="UpdatePanel1" runat="server"> 
     <ContentTemplate> 
      <asp:PlaceHolder runat="server" ID="myPlaceHolder"></asp:PlaceHolder> 
     </ContentTemplate> 
     <Triggers> 
      <asp:AsyncPostBackTrigger ControlID="btnAddTextBox" EventName="Click" /> 
     </Triggers> 
    </asp:UpdatePanel> 
    <br /> 
    </div> 
    <br /> 
    <asp:Button ID="btnAddTextBox" runat="server" Text="Add TextBox" OnClick="btnAddTextBox_Click" /> 
    <br /><br /> 
    <asp:UpdatePanel ID="UpdatePanel2" runat="server"> 
     <ContentTemplate> 
      <asp:Button runat="server" ID="MyButton" Text="Get Values." OnClick="MyButton_Click" /> 
      <br /><br /> 
      <asp:Label runat="server" ID="MyLabel"></asp:Label> 
     </ContentTemplate> 
    </asp:UpdatePanel> 
</div> 
</form> 

.aspx.cs

static int myCount = 0; 
    private TextBox[] dynamicTextBoxes; 

    protected void Page_PreInit(object sender, EventArgs e) 
    { 
     Control myControl = GetPostBackControl(this.Page); 

     if ((myControl != null)) 
     { 
      if ((myControl.ClientID.ToString() == "btnAddTextBox")) 
      { 
       myCount = myCount + 1; 
      } 
     } 
    } 

    protected override void OnInit(EventArgs e) 
    { 
     base.OnInit(e); 
     dynamicTextBoxes = new TextBox[myCount]; 
     int i; 
     for (i = 0; i < myCount; i += 1) 
     { 
      TextBox textBox = new TextBox(); 
      textBox.ID = "myTextBox" + i.ToString(); 
      myPlaceHolder.Controls.Add(textBox); 
      dynamicTextBoxes[i] = textBox; 
      LiteralControl literalBreak = new LiteralControl("<br />"); 
      myPlaceHolder.Controls.Add(literalBreak); 
     } 
    } 

    protected void btnAddTextBox_Click(object sender, EventArgs e) 
    { 
     // Handled in preInit due to event sequencing. 
    } 

    protected void MyButton_Click(object sender, EventArgs e) 
    { 
     MyLabel.Text = ""; 
     foreach (TextBox tb in dynamicTextBoxes) 
     { 
      MyLabel.Text += tb.Text + " :: "; 
     } 
    } 

    public static Control GetPostBackControl(Page thePage) 
    { 
     Control myControl = null; 
     string ctrlName = thePage.Request.Params.Get("__EVENTTARGET"); 
     if (((ctrlName != null) & (ctrlName != string.Empty))) 
     { 
      myControl = thePage.FindControl(ctrlName); 
     } 
     else 
     { 
      foreach (string Item in thePage.Request.Form) 
      { 
       Control c = thePage.FindControl(Item); 
       if (((c) is System.Web.UI.WebControls.Button)) 
       { 
        myControl = c; 
       } 
      } 
     } 
     return myControl; 
    } 
6

動態生成的控件不保持狀態。你必須自己維護它。您可以使用一些隱藏字段來保持控件的狀態,這些控件將在服務器端用於提取狀態。 Asp.net使用隱藏字段來維護請求之間的狀態,您可以在源代碼中看到__VIEWSTATE

在ASP.NET頁面中,視圖狀態表示在上次在服務器上處理它時 頁面的狀態。它用於構建調用上下文 ,並保留跨同一頁面的兩個連續請求的值。通過 默認情況下,狀態被在客戶端上使用隱藏字段 添加到頁面仍和 頁面請求被處理之前被恢復在服務器上。視圖狀態行駛來回的 頁面本身,但並不代表或包含的 相關的客戶端頁面顯示,Reference任何信息。

+0

單獨使用時是這樣,但是如果將動態創建的控件添加到PlaceHolder(或其他WebControl),則會保持動態控件的狀態。只要您在頁面加載時(或之前)重新創建動態控件,在回發時也會保留狀態信息。 – Radderz

13

使用動態控件時,您必須記住它們將存在,直到下一次postback.ASP.NET將不會重新創建一個動態添加的控件。如果您需要重新創建一個控制多次,您應該執行在pageLoad的事件處理程序中創建控件(你目前只是創建僅第一次使用條件的文本框:IsPostabck)。這具有允許您在動態控制中使用視圖狀態的額外好處。儘管視圖狀態的Page.Load事件之前恢復正常,如果創建的處理程序pageLoad的事件控制,ASP.NET將適用於任何視圖狀態信息,它具有pageLoad的事件處理結束後。

因此,刪除的條件:!的IsPostBack,所以,每次頁面加載後,還創建TextBox控件。在PageLoad處理程序完成後,您還將看到保存的文本狀態框。 [顯然你沒有禁用ViewState! ]

例子:

protected void Page_Load(object sender, EventArgs e) 
{ 

    TextBox txtBox = new TextBox(); 
    // Assign some text and an ID so you can retrieve it later. 

    txtBox.ID = "newButton"; 
    PlaceHolder1.Controls.Add(txtBox); 

} 

現在它運行後,請在文本框中輸入任何東西,看到當你點擊,導致回發任意按鈕會發生什麼。文本框仍然保持其狀態!

+1

您能否詳細說明ViewState及其如何影響動態控件? – Zorgarath

+0

祝福你!好的解決方案 – ARNDG2

0

其實,我用JavaScript來完成我的任務。 ,它是這樣的:

<form id="form1" runat="server" enctype="multipart/form-data" method="post"> 
     <span style="font-family: Arial">Click to add files</span>&nbsp;&nbsp; 
     <input id="Button1" type="button" value="add" onclick="AddFileUpload()" /> 
     <br /> 
     <br /> 
     <div id="FileUploadContainer"> 
      <!--FileUpload Controls will be added here --> 
     </div> 
     <asp:HiddenField ID="HdFirst1" runat="server" Value="" /> 
     <br /> 
     <asp:Button ID="btnUpload" runat="server" Text="Upload" OnClick="btnUpload_Click" /> 
    </form> 

腳本:

<script type="text/javascript"> 
     var counter = 0; 

     function AddFileUpload() { 

      var div = document.createElement('DIV'); 
      div.innerHTML = '<input id="file' + counter + '"name = "file' + counter + '"type="text"/><input id="file' + counter + '" name = "file' + counter + '" type="file" /><input id="Button' + counter + '" type="button" value="Remove" onclick = "RemoveFileUpload(this)" />'; 

      document.getElementById("FileUploadContainer").appendChild(div); 
      counter++; 
     } 
     function RemoveFileUpload(div) { 
      document.getElementById("FileUploadContainer").removeChild(div.parentNode); 
     } 

     function mydetails(div) { 
      var info; 
      for (var i = 0; i < counter; i++) { 
       var dd = document.getElementById('file' + i).value; 
       info = info + "~" + dd; 
      } 
      document.getElementById('<%= HdFirst1.ClientID %>').value = info; 
     } 
    </script> 

,並在Upload_Click按鈕:

for (int i = 0; i < Request.Files.Count; i++) 
     {   
      string strname = HdFirst1.Value; 
      string[] txtval = strname.Split('~'); 
      HttpPostedFile PostedFile = Request.Files[i]; 
      if (PostedFile.ContentLength > 0) 
      { 
       string FileName = System.IO.Path.GetFileName(PostedFile.FileName); 
       // string textname= 
       //PostedFile.SaveAs(Server.MapPath("Files\\") + FileName); 
      } 
     } 
13

所有你需要做的是重新實例/重新初始化動態在頁面加載事件之前或之內進行控制,每次在回發期間並將此控件添加到頁面/窗體/佔位符。然後,發佈的數據將通過父控件調用LoadPostData方法自動分配給控件。

檢查的文章,以及如何編寫動態控制碼 - How to maintain dynamic control events, data during postback in asp.net

enter image description here

+0

現在我清楚瞭解動態控制狀態管理,謝謝vivek。 – Rohit

+0

+1爲詳細的支持文章。這是用於回發/事件的動態控件的下劃線工作的重要參考。 – Radderz

4

當你與動態控制的工作就刪除此行

if (!IsPostBack) 
0

他們不會能夠保持其狀態在回發和他們的數據丟失原因他們沒有任何viewstate維護他們的數據。

您只需要將創建的控件數據動態保存到ViewState 中,並在回發時將數據加載到頁面中,並且您完成了 。

public Dictionary<Guid, string> UcList 
{ 
    get { return ViewState["MyUcIds"] != null ? (Dictionary<Guid, string>)ViewState["MyUcIds"] : new Dictionary<Guid, string>(); } 
    set { ViewState["MyUcIds"] = value; } 
} 

public void InitializeUC() 
{ 
    int index = 1; 
    foreach (var item in UcList) 
    { 
     var myUc = (UserControls_uc_MyUserControl)LoadControl("~/UserControls/uc_MyUserControl.ascx"); 
     myUc.ID = item.Value; 
     pnlMyUC.Controls.AddAt(index, myUc); 
     index++; 
    } 
} 

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!IsPostBack) 
     LoadControl(); 
    else 
     InitializeUC(); 
} 

在這裏您可以找到關於動態控件的回發和回發的最佳理解。 Retain dynamic control values in every postback or event click

enter image description here