2009-02-16 6 views
13

Tôi đã mã thực sự đơn giản sau đâyThêm điều khiển tự động để một UpdatePanel trong ASP.NET AJAX

<asp:ScriptManager ID="ScriptManager1" runat="server"> 
</asp:ScriptManager> 

<asp:UpdatePanel ID="UpdatePanel1" runat="server"> 
<ContentTemplate> 
    <asp:PlaceHolder ID="PlaceHolder1" runat="server"> 
    </asp:PlaceHolder> 
    <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" /> 
</ContentTemplate> 
</asp:UpdatePanel> 

Và codebehind

protected void Button1_Click(object sender, EventArgs e) 
{ 
    Literal literal = new Literal(); 
    literal.Text = DateTime.Now.ToString(); 
    literal.ID = DateTime.Now.Ticks.ToString(); 

    // These both work fine the first time the button is clicked 
    // but the second time nothing is added. 
    UpdatePanel1.ContentTemplateContainer.Controls.Add(literal); 
    PlaceHolder1.Controls.Add(literal); 
} 

Vấn đề của tôi xuất phát ở chỗ điều khiển Literal chỉ bao giờ thêm Một lần. Tôi đã lùng sục các trang google và blog (cộng với sách) nhưng không may mắn. Tôi đang thiếu gì?

Trả lời

22

Trong asp.net, các điều khiển trong tệp ASPX được tạo tự động trên mỗi bài đăng. Các điều khiển bạn đã tạo không có trong mã ASPX do đó khung công tác không tạo chúng cho bạn. Lần đầu tiên bạn thực hiện phương thức Button1_Click, bạn thêm một điều khiển bổ sung vào trang. Lần thứ hai bạn thực hiện phương thức Button1_Click, bạn đang ở trên một bài đăng khác và nút thêm đầu tiên đã bị lãng quên. Vì vậy, kết quả của postback đó là bạn nhận được thêm một nút nữa.

này sẽ tạo một điều khiển thêm mỗi khi bạn nhấp vào nút (mặc dù các timestamps sẽ cập nhật mỗi khi bạn nhấn nút vì các điều khiển đang được tái tạo)

protected void Button1_Click(object sender, EventArgs e) 
{ 
    int count = 0; 

    if (ViewState["ButtonCount"] != null) 
    { 
     count = (int)ViewState["ButtonCount"]; 
    } 

    count++; 
    ViewState["ButtonCount"] = count; 

    for (int i = 0; i < count; i++) 
    { 
     Literal literal = new Literal(); 
     literal.Text = DateTime.Now.ToString(); 
     literal.ID = DateTime.Now.Ticks.ToString(); 

     UpdatePanel1.ContentTemplateContainer.Controls.Add(literal); 
     PlaceHolder1.Controls.Add(literal); 
    }    
} 
+0

Chính xác những gì tôi đã sau đó, nhờ –

1

Tôi đồng ý với câu trả lời trên Tuy nhiên, cách tiếp cận này sẽ không lưu trạng thái của các điều khiển động (hoặc để được chính xác, nó sẽ lưu trạng thái nhưng không tải chúng trở lại). Trạng thái xem tải được gọi trong phần Tải sự kiện của vòng đời trang, nơi nó gán trở lại các giá trị điều khiển được lưu trong trạng thái xem. Tuy nhiên, nếu các điều khiển không được tạo bởi thời gian này, chúng không thể được nạp với dữ liệu trước đó để trạng thái được duy trì, các điều khiển mới phải được tạo lại vào hoặc trước khi tải sự kiện.

protected void Page_Load(object sender, EventArgs e) 
{ 
    //PS: Below approach saves state as id is constant, it simply generates a new control with same id hence viewstate loads the value 
    if (IsPostBack) 
    { 
     int count = 0; 

     if (ViewState["ButtonCount"] != null) 
     { 
      count = (int)ViewState["ButtonCount"]; 
     } 

     count++; 
     ViewState["ButtonCount"] = count; 

     for (int i = 0; i < count; i++) 
     { 
      TextBox literal = new TextBox(); 
      //literal.Text = DateTime.Now.ToString(); 
      literal.ID = "Textbox" + i.ToString(); 

      //UpdatePanel1.ContentTemplateContainer.Controls.Add(literal); 
      PlaceHolder1.Controls.Add(literal); 

     } 
    } 
} 

Dynamically adding controls View State and postback

+1

Đồng ý, đây là tốt hơn. Giữ ID giống nhau trên postback cho phép viewstate áp dụng chính xác. Howver, điều này nên được thực hiện trong Init của trang theo http://msdn.microsoft.com/en-us/library/ms972976.aspx –