2008-12-08 78 views
1

好的時候,以顯示我完全缺乏知識的web表單的所有東西,但在這裏。我擴展了Panel控件,並且OnPreRender在其中添加了一些額外的控件(爲簡單起見,我們只說1個文本框)。從這裏我只是讓面板渲染方法做它的事情。服務器控件和查看狀態

我遇到的問題是,顯然每次該控件被重新渲染時,它只是在面板中再次粘貼相同的TextBox,並在OnPreRender方法中編碼值。現在我實際上並不想每次都重新填充面板,我想在第一次加載時將textbox控件粘貼在那裏,並讓它們從控件/視圖狀態緩存中重新加載。在這種情況下,我只是在面板中粘貼單個文本框的示例,如果文本框的值發生更改併發生回發,我希望該值保持更改後的值。

真的很基本的webforms我知道的東西,但我從來沒有必須在我的時間創建自定義控件。任何幫助表示讚賞。

克里斯。

回答

3

您需要(重新)在OnInit中創建子控件(文本框) - 以便在調用LoadViewState和ProcessPostBackData時它在那裏。

查看server control lifecycle瞭解更多信息。

+0

乾杯,這是正確的。 – Owen 2008-12-08 17:00:07

0

在代碼中,如果您需要viewstate服務,您將需要管理視圖狀態信息的還原。

這裏的一個很好的例子是微軟的View State example。代碼示例中引用了一些其他項目,但它應該可以幫助您沿着正確的道路前進。

1

ASP.NET中的動態控件非常棘手,尤其是如果您對webforms和頁面生命週期不熟悉的話。如果你可以避免動態控制,那就這樣做。改用controlName.Visible = false和其他技巧。如果您必須閱讀this article。經驗法則,在頁面生命週期的早期添加控件,稍後在頁面生命週期中引用它們。 PreRender幾乎是最終目標,這是一個不常見的添加和使用控件的地方。

1

不知道這是否適用於.Net(我認爲2.0或更高版本)的所有版本,但有一個名爲CreateChildControls的方法並不完全是生命週期的一部分,它基本上在EnsureChildControls方法是調用。默認情況下,它在PreRender之前調用,如果它不是回發。所以基本上你的代碼應該是這樣的:

public class SomeControl : WebControl, INamingContainer 
{ 
    private TextBox someTextBox; 

    protected override void CreateChildControls() 
    { 
    base.CreateChildControls(); 

    someTextBox= new TextBox(); 
    someTextBox.ID = "tbxMain"; 

    Controls.Add(textboxToCheck); 
    } 
} 

現在部分不是,除非你叫EnsureChildControls,你不能100%地肯定存在的控件之前對你控制的公共屬性被填滿ViewState加載。這是什麼意思?那麼把代碼前加一個屬性CssClass屬性:

public class SomeControl : WebControl, INamingContainer 
{ 
    private TextBox someTextBox; 

    protected override void CreateChildControls() 
    { 
    base.CreateChildControls(); 

    someTextBox= new TextBox(); 
    someTextBox.ID = "tbxMain"; 

    Controls.Add(textboxToCheck); 
    } 

    public String CssClass { get; set; } 
} 

在CreateChildControls中,你不會想這樣的:

someTextBox.CssClass = CssClass; 

因爲沒有辦法,以確保控制還不存在。還有,你可以處理這幾種方法:

公共字符串的CssClass { 得到 { EnsureChildControls(); return someTextbox.CssClass; }

set 
{ 
    EnsureChildControls(); 
    someTextbox.CssClass = value; 
} 

在這個例子中我打電話EnsureChildControls(假設您正在設置CssValue在CreateChildControls方法的文本框),並設置或文本框獲得。

另一種方法是把任何東西在的OnPreRender方法取決於控制的公共屬性:

protected override void OnPreRender(EventArgs e) 
{ 
    someTextbox.CssClass = CssClass; 
} 

從而避免擔心財產被ViewState的負載時已填寫的混亂。

一注:

使用作INamingContainer的也很重要。基本上,所有這些都確保父控件上的控件具有一個在頁面上唯一的id,方法是將父項的名稱(也許更多)應用於id。基本上,如果父ID是Parent,並且子控件ID是Child,則ID可能會顯示爲Parent_Child。這將解決ViewState不能正確填充屬性或根本不填充問題。