2010-09-16 62 views
4

我無法在ListView中獲取動態創建的控件的輸入值。在ListView中獲取動態添加控件的值

這裏是我的ListView:

<asp:ListView ID="lvQuestions" runat="server" DataKeyNames="ProductQuestionId" onitemdatabound="lvQuestions_ItemDataBound"> 
    <LayoutTemplate> 
     <table> 
      <tr runat="server" id="itemPlaceholder"></tr> 
     </table> 
    </LayoutTemplate> 
    <ItemTemplate> 
      <tr> 
       <td><%# Eval("Question") %></td> 
       <td> 
        <asp:PlaceHolder ID="plControl" runat="server" /> 
        <asp:HiddenField ID="hfQuestionId" runat="server" /> 
       </td> 
      </tr> 
    </ItemTemplate>   
</asp:ListView> 
<asp:Button ID="btnSubmit" runat="server" Text="Submit" onclick="btnSubmit_Click" /> 

在我的ItemDataBound處理程序我添加一個文本框或其他控件的佔位符。控件類型取決於項目,但爲了保持簡單,我們假設它始終是文本框。控件的ID也是動態的。

// create a textbox control 
TextBox txtbx = new TextBox(); 
txtbx.ID = "txtQuestion_" + productQuestionId.ToString(); //productQuestionId is the datakey value of this ListViewItem 
placeholder.Controls.Add(txtbx); 

當用戶點擊按鈕我需要能夠得到他們填寫的值。

在我的研究中,我發現我需要首先重新創建動態添加的控件,以獲取頁面生命週期的值。

以下是我在我的按鈕處理程序重新創建控件:

foreach (ListViewDataItem item in lvQuestions.Items) 
    { 
     HiddenField hdField = (HiddenField)item.FindControl("hfQuestionId"); 
     PlaceHolder plcHolder = (PlaceHolder)item.FindControl("plControl"); 
     TextBox txtbx = new TextBox(); 
     txtbx.ID = "txtQuestion_" + hdField.Value; 
     plcHolder.Controls.Add(txtbx); 
    } 

然後在相同的處理一個代碼塊我重新迭代通過ListViewDataItems並找到控制:

foreach (ListViewDataItem item in lvQuestions.Items) 
    { 
     HiddenField hdField = (HiddenField)item.FindControl("hfQuestionId"); 
     PlaceHolder plcHolder = (PlaceHolder)item.FindControl("plControl"); 
     TextBox txtbx = (TextBox)plcHolder.FindControl("txtQuestion_" + hdField.Value); 
     if (txtbx != null) 
     { 
      Response.Write("TextBox Found:" + txtbx.Text); 
     } 
    } 

該文本框被找到,但沒有任何價值。這就像我剛剛在上一個塊中的新文本框中寫過的那樣。如果我刪除了前面的代碼塊,就沒有發現任何文本框。

有人能幫我解決我在這裏失蹤的事嗎?

謝謝。

回答

3

正如您已經發現的那樣,這是一個生命週期問題。嘗試在ListView.ItemCreated事件中創建動態控件,而不是ListView.ItemDataBound事件。

+0

謝謝你,Phaedrus,這工作!我從來沒有讀過關於在ItemCreated事件中創建控件的任何內容。我在這裏移動了創建並刪除了我的代碼塊,以便在按鈕提交處理程序中重新創建控件。再次感謝。 – DahlinDev 2010-09-17 03:45:56

1

我認爲這裏的問題是,在您嘗試讀取這些值之前,生命週期沒有機會使用它們提交的值填充控件。

通常,如果我打算做這樣的事情,我會重新創建Page_Init事件中的控件,在將值加載到控件之前發生這種情況。您也可以在特定控件的Init事件中執行此操作,但這是需要將其他控件重新添加到頁面的位置。

+0

我試着在Page_Init中添加控件的重新創建。我添加了邏輯,如果(Page.IsPostBack && lvQuestions.Visible)只在表單提交併且實際顯示問題時重新創建它們。這樣做時沒有找到控件。 – DahlinDev 2010-09-17 03:43:04

0

這並沒有爲我工作,所以我不得不這樣做在PreInit通話

protected override void OnPreInit(EventArgs e) 
    { 
     base.OnPreInit(e); 

     foreach (ListViewDataItem item in lvQuestions.Items) 
     { 
      HiddenField hdField = (HiddenField)item.FindControl("hfQuestionId"); 
      PlaceHolder plcHolder = (PlaceHolder)item.FindControl("plControl"); 
      if (hdField != null && plcHolder != null) 
      { 
       TextBox txtbx = new TextBox(); 
       txtbx.ID = "txtQuestion_" + hdField.Value; 
       plcHolder.Controls.Add(txtbx); 
      } 
     } 

    } 

和我剛搬到這個方法返回ItemDataBound事件

protected void lvQuestions_ItemDataBound(object sender, ListViewItemEventArgs e) 
    { 
     object datakey = lvQuestions.DataKeys[e.Item.DataItemIndex].Value; //get datakey here 

     TextBox txtbx = new TextBox(); 
     txtbx.EnableViewState = true; 
     txtbx.ID = "txtQuestion_" + datakey.ToString(); //productQuestionId is the datakey value of this ListViewItem 
     PlaceHolder pl = e.Item.FindControl("plControl") as PlaceHolder; 
     HiddenField hf = e.Item.FindControl("hfQuestionId") as HiddenField; 
     if (pl != null) 
      pl.Controls.Add(txtbx); 
     if (hf != null) 
      hf.Value = datakey.ToString(); 
    } 

然後它開始工作。