透過使用者互動才動態載入使用者控制項的問題

需要動態載入使用者控制項,且是透過使用者觸發後再去決定載入何者,假設頁面呈現如下:

<form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always">
        <ContentTemplate>
            <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
            <br />
            <asp:Button ID="btUpdate" runat="server" Text="Update" OnClick="btUpdate_Click" />
            &nbsp;<asp:Button ID="btNext" runat="server" OnClick="btNext_Click" Text="Next" />
            &nbsp;<asp:Button ID="btBack" runat="server" OnClick="btBack_Click" Text="Back" />
        </ContentTemplate>
    </asp:UpdatePanel>
    </form>

程式碼為:

01     protected void Page_Init(object sender, EventArgs e)
02     {
03         if (!IsPostBack)
04         {
05             loadctrl("c1.ascx");
06             Session["path"] = "c1.ascx";
07         }

08         else
09         {
10             if (Session["path"] != null)
11             {
12                 loadctrl(Session["path"].ToString());
13             }

14         }

15             
16     }

17
18     private void loadctrl(string s)
19     {
20         PlaceHolder1.Controls.Clear();
21         PlaceHolder1.Controls.Add((UserControl)Page.LoadControl(s));
22     }

23
24     protected void btNext_Click(object sender, EventArgs e)
25     {
26         loadctrl("c2.ascx");
27         Session["path"] = "c2.ascx";
28     }

29     protected void btBack_Click(object sender, EventArgs e)
30     {
31         loadctrl("c1.ascx");
32         Session["path"] = "c1.ascx";  
33     }

34     protected void btUpdate_Click(object sender, EventArgs e)
35     {    // for postback
36     }

 c1.ascx 與 c2.ascx都內含一個TextBox控制項,ID皆為TextBox1。以此作法在第一次載入頁面時,c1.ascx載入的TextBox控制項輸入內容後,按下 Update 按鈕(觸發Postback)之後,其內容會自動被保留。然後按下 Next 按鈕,載入c2.ascx發現c1:TextBox1的內容直接帶到c2中的TextBox1中(原因是ID相同);再者,此時按下Update按鈕後,c2:TextBox1的內容就會消失,再輸入一次內容,然後再按Update按鈕,結果內容會被保留。c2.ascx第一次載入時無法自動儲存狀態,按下Back按鈕回到c1.ascx也是同樣情形。所以動態更換控制項後,第一次postback無法自動儲存狀態。於是天真的改了程式碼:

01     static bool postbackagain;
02
03     protected void Page_Init(object sender, EventArgs e)
04     {
05         if (!IsPostBack)
06         {
07             loadctrl("c1.ascx");
08             Session["path"] = "c1.ascx";
09             postbackagain = false;
10         }

11         else
12         {
13             if (Session["path"] != null)
14             {
15                 loadctrl(Session["path"].ToString());
16             }

17         }
          
18     }

19     private void loadctrl(string s)
20     {
21         PlaceHolder1.Controls.Clear();
22         PlaceHolder1.Controls.Add((UserControl)Page.LoadControl(s));
23         if (!postbackagain)
24         {
25             postbackagain = true;
26             ScriptManager.RegisterStartupScript(Page, typeof(Page),  
27              "postback", "__doPostBack();", true);
28         }

29     }

30     protected void btNext_Click(object sender, EventArgs e)
31     {
32         postbackagain = false;
33         loadctrl("c2.ascx");
34         Session["path"] = "c2.ascx";
35     }

36     protected void btBack_Click(object sender, EventArgs e)
37     {
38         postbackagain = false;
39         loadctrl("c1.ascx");
40         Session["path"] = "c1.ascx";  
41     }

42     protected void btUpdate_Click(object sender, EventArgs e)
43     {  // for postback
44     }

此修改主要是在載入新的控制項之後,重新PostBack一次;因為一時間找不到應該怎麼做才適合,所以用此方式暫時處理。(還有一個問題是兩個UserControl內的子控制項若有相同ID就會發生自動帶值的問題,在開發上是方便也是困擾。)

搜尋了一下文章,原來是沒有給UserControl的ID值,才會有如此情形(~.~)。所以改了最初的原始碼18-22行如下:

private void loadctrl(string s)
{
    PlaceHolder1.Controls.Clear();
    UserControl Obj = (UserControl)Page.LoadControl(s);
    Obj.ID = "abc";
    PlaceHolder1.Controls.Add(Obj);
}

這樣就解決了。參考以下連結:

wljcan.cnblogs.com/archive/2004/06/14/15604.html

www.cnblogs.com/hjf1223/archive/2006/06/20/430475.html

Add Comment DotBlogs Tags: ASP 閱讀數 : 332 訂閱

關連文章

 

回覆

目前沒有回應.

標題*
姓名*
電子郵件 (never displayed)
 
個人網頁
回覆*

登入後使用進階評論
Please add 2 and 5 and type the answer here: