2010-09-16 57 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(); 
    } 

然后它开始工作。