2012-01-31 43 views
1

背景在回發上,Repeater的DataTable數據源爲空?

我有個用戶控件(一個.ascx文件),其被動態插入到一個asp:在頁面上佔位符控制。該用戶控件包含一個asp:Repeater,我綁定到一個DataTable。

理論上,在用戶控件的第一次加載時,初始化DataTable並添加3個空行。用戶控件上的按鈕一次一個地向中繼器添加額外的空行。

問題

問題是,頁面上的任何回發事件(即在本例中被點擊的按鈕)後,對中繼數據表是空的。

用戶控件(.ascx) (簡化的)

<asp:TextBox ID="controlOutsideRepeater" runat="server" /> 
<asp:Repeater ID="myRepeater" runat="server"> 
    <ItemTemplate> 
    <p><asp:Textbox ID="firstControlInRepeater" runat="server" text='<%# DataBinder.Eval(Container.DataItem, "A") %>' /></p> 
    <p><asp:Textbox ID="secondControlInRepeater" runat="server" text='<%# DataBinder.Eval(Container.DataItem, "B") %>' /></p> 
    </ItemTemplate> 
</asp:Repeater> 
<asp:LinkButton ID="addItemButton" runat="server" Text="Add Item" onclick="addNewItem" /> 

代碼的背後(.ascx.cs) (也被簡化)

public DataTable items { 
    get { 
    object i = ViewState["items"]; 
    if (i == null) { 
     DataTable t = new DataTable(); 
     t.Columns.Add("A"); 
     t.Columns.Add("B"); 
     // add 3 blank items/rows: 
     t.Rows.Add(t.NewRow()); 
     t.Rows.Add(t.NewRow()); 
     t.Rows.Add(t.NewRow()); 
     ViewState["items"] = t; 
     return t; 
    } else { 
     return (DataTable)i; 
    } 
    set { ViewState["items"] = value; } 
} 

protected void Page_Init(object sender, EventArgs e) { 
    myRepeater.DataSource = this.items; 
    myRepeater.DataBind(); 
} 

public void addNewItem(object sender, EventArgs e) { 
    DataRow r = this.items.NewRow(); 
    this.items.Rows.Add(r); 
    myRepeater.DataBind(); 
} 

行爲

第一次加載UserControl時,Repeater包含3個空項目:好!然而,在轉發器內外的文本框中輸入一些文本並單擊「添加項目」LinkBut​​ton後,頁面會執行刷新/回發並顯示4個空項目,但文本框外側 - Repeater保留其文本。再次單擊「添加項目」LinkBut​​ton也會執行回發並仍顯示4個空項目,但Repeater外部的TextBox會再次保留其文本。

我的瘋狂猜測

我已經試過包裝在一個(!Page.IsPostBack)直放站綁定,但是這阻止了中繼從-ever-的束縛,爲用戶控件只能以編程方式添加到PostBack之後的頁面(頁面上的按鈕單擊添加UserControl,然後頁面會檢查每個PostBack以查看是否應該存在用戶控件,並在需要時將其重新添加到頁面中)。所以我猜測頁面在每個PostBack上重新創建用戶控件都存在問題,但無法解釋爲什麼Repeater外部的TextBox會保留它的值,以及爲什麼ViewState似乎不記得我的項目(在每個回發ViewState [「項目」]爲空,並在getter內重新構建)。

幫助!

回答

1

問題是,當你真的只想在第一個請求上綁定數據時,你是數據綁定每一個請求。由於您沒有在第一頁加載時綁定數據,因此您必須檢查您是否以!Page.IsPostBack以外的方式綁定了數據。你可以添加一個屬性到你的用戶控件來處理這個問題,然後檢查每個頁面加載/頁面init。

更新:從意見

更多的細節我看到你的AddItem()現在。儘管我並不完全確定爲什麼,但我仍然用這種方法使用viewstate時遇到了問題。我必須做得更像下面這樣:

public void addNewItem(object sender, EventArgs e) { 
    DataTable theItems = this.items; 
    DataRow r = theItems.NewRow() 
    theItems.Rows.Add(r); 
    this.items = theItems 
    myRepeater.DataBind(); //I'm not sure if this belongs here because of the reasons said before 
} 
+0

感謝您的回覆。我試圖通過在我的頁面上添加一個空標籤,並在Page_Load上檢查標籤的文本是否爲空。如果爲空,我爲標籤設置一個文本值並執行我的數據綁定(我註釋掉了Page_Init中的數據綁定),如果標籤具有文本值,我將跳過數據綁定。其結果是中繼器第一次正確綁定(帶有3個空項目),但在後續回發中完全沒有綁定。在這裏的一些搜索表明,中繼器需要綁定每個請求... – DaveD 2012-01-31 01:10:58

+0

我不知道中繼器的這種行爲。 MSDN上的這篇文章舉例說明了一個if!IsPostBack塊中發生的所有綁定。 http://msdn.microsoft.com/en-us/library/s1th73f0.aspx我唯一的猜測是視圖狀態沒有被更新或正確讀取。這聽起來像它的綁定罰款,如果你有3空白行。問題是viewstate每次都是空的。你什麼時候回寫ViewState(除了你設置的方法)? – SpartanDonut 2012-01-31 01:19:04

+0

只是在getter和setter中,並間接地在addItem()事件處理函數中(因爲它調用setter) – DaveD 2012-01-31 01:25:25