2010-10-13 36 views
0

我熟悉在頁面的第一次加載和後續回發時創建並保留動態控件,但我遇到以下問題用戶啓動情景......如何添加基於用戶輸入的持久動態控件(不是在初始頁面加載時)

在我的演示中,我有一個佔位符,兩個按鈕和一個文字

<div> 
    <asp:PlaceHolder ID="phResponses" runat="server" /> 
</div> 
<div> 
    <asp:Button ID="btnAdd" Text="Add" runat="server" OnClick="Add"/> 
    <asp:Button ID="btnInspect" Text="Inspect" runat="server" OnClick="Inspect"/> 
</div> 
<div> 
    <asp:Literal ID="litResult" runat="server"/> 
</div> 

我希望用戶能夠點擊添加按鈕來提供響應,所以我有...

protected void Page_Init(object sender, EventArgs e) 
{ 
    BuildControls(); 
} 

protected void Add(object sender, EventArgs e) 
{ 
    BuildControls(); 
} 

protected void BuildControls() 
{ 
    phResponses.Controls.Add(new LiteralControl { ID = "response_" + _Count.ToString() }); 
    _Count++; 
} 

_Count是一個靜態成員變量,使我能夠擁有新控件的唯一ID。我意識到我需要重建Page_Init上的動態控件,但問題是每次回發都會有2個新的文字控件。另外,如果將任何Text屬性放入新控件,則在重新構建控件時會丟失。

那麼,如何避免添加多個控件,以及在重建這些控件時如何堅持新添加的屬性?

我使用以下方法來檢查響應

protected void Inspect(object sender, EventArgs e) 
{ 
    foreach (var control in phResponses.Controls) 
    { 
     if (control is LiteralControl) 
     { 
      litResults.Text += "<p>" + control.Text + " : " + control.ID + "</p>"; 
     } 
    } 
} 

這本身增加了,因爲在Page_Init

重建

回答

0

我倒是不知道,我不太明白你問其他不必要的控制,但看起來你只是想確保BuildControls只在每個生命週期中被調用一次。你可以做,通過進行以下修改:

  1. 添加新private bool _isControlsBuilt = false;
  2. 更改Page_Init檢查_isControlsBuilt,然後致電BuildControls
  3. 設置_isControlsBuilttrueBuildControls之內。
  4. 確保BuildControls發生在page lifecycle之前,而不是Page_Init

至於丟失回發控件的值,這將是他們從來沒有達到視圖狀態。我不知道這是否會工作,但我的第一個猜測是添加一行到BuildControls末調用Page.RegisterRequiresControlState

protected void BuildControls() 
{ 
    LiteralControl newLiteral = new LiteralControl { ID = "response_" + _Count }; 
    this.RegisterRequiresControlState(newLiteral); 
    phResponses.Controls.Add(newLiteral); 

    _Count++; 
    _isControlsBuilt = true; 
} 

如果不工作(這可能意味着它的_view_state,而不是_control_state在這裏對你很重要),你可能需要看看滾動你自己的viewstate。我寫了關於如何在my answer to #3854193中做到這一點,您可能會覺得有用。

相關問題