BloggerAds

2011年6月22日 星期三

ASP.NET 動態新增Control、UserControl在PostBack後的處理

當有控制項(Control)或使用者控制項(UserControl)在頁面中是屬於動態新增的,若在頁面上不會觸發PostBack事件,其實是很好處理的,在使用上不會有什麼大問題。問題在於觸發PostBack的情況是很容易發生的,當PostBack發生後,你會發現所有動態產生的控制項通通不見了,這個問題實在是很惱人,所以在動態新增控制項時,要做一些特別的處理,程式才會乖乖的照著你的意思跑。

動態增加控制項的方法如下(以下以使用者控制項為例):
//載入User Control
UserControl1 ucObj=(UserControl1)LoadControl("~/UserControl1.ascx");

//若為一般控制項(Control),只要new一個新物件即可
//以TextBox為例,TextBox txtObj = new TextBox();

panel1.Controls.Add(ucObj); //加在Panel中
若上述程式放在按鈕的Click事件中,當User每按一次按鈕時,控制項照理說會一直增加,但實際上卻一直只有一個UserControl出現在畫面上。出了什麼問題? 原因就是沒有ViewState,所以PostBack後,原先增加的控制項就消失了,只有最後新增的一個控制項存在。因為是動態新增的,所以在Page_Init時.NET沒辦法將控制項重建,而解決方式就是用ViewState或Session將新增的控制項總數記下來,在Page_Load時將動態新增的控制項加回去,在新增控制項時,要多記錄控制項數目,所以上面的程式要改成如下:
//載入User Control
UserControl1 ucObj=(UserControl1)LoadControl("~/UserControl1.ascx");

panel1.Controls.Add(ucObj); //加在Panel中

if (ViewState["UcCount"] != null) {
    //記錄控制項數目
    ViewState["UcCount"]=           (int.Parse(ViewState["UcCount"].ToString())+1).ToString();
}else{
    ViewState.Add("UcCount", "1");
}
另外,在Page_Load事件中,要加入下列程式碼:
if (ViewState["UcCount"] != null) {
    for (int i = 1; i <= int.Parse(ViewState["UcCount"].ToString()); i++) {                              panel1.Controls.Add((UserControl1)LoadControl("~/UserControl1.ascx"));
    }
}
另外要注意的是,新增控制項時不可以設定ID(ex. ucObj.ID = "xxx"),否則每次PostBack時,都會視為一個新的物件,而讓PostBack前輸入的值消失。

參考資料:
http://social.msdn.microsoft.com/forums/zh-TW/236/thread/c18da009-fbcd-437b-9f9c-f758ade1e477/

沒有留言:

張貼留言