【问题标题】:Get values of dynamically added controls in ListView获取 ListView 中动态添加的控件的值
【发布时间】:2011-04-13 11:13:47
【问题描述】:

我无法在 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 处理程序中,我将 TextBox 或其他控件添加到占位符。控件类型取决于项目,但为了简单起见,我们假设它始终是一个文本框。控件的 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);
        }
    }

找到文本框,但没有值。就像我刚刚在前一个块中用新的文本框覆盖了文本框。如果我删除前面的代码块,则找不到任何文本框。

有人可以帮我解决我在这里缺少的东西吗?

谢谢。

【问题讨论】:

    标签: asp.net listview dynamic controls


    【解决方案1】:

    我认为这里的问题是,在您尝试读取这些值之前,生命周期没有机会使用它们提交的值填充控件。

    通常,如果我要执行这样的操作,我会在 Page_Init 事件中重新创建控件,该事件发生在将值加载到控件之前。您也可以在特定控件的 Init 事件中执行此操作,但这是需要将其他控件重新添加到页面的地方。

    【讨论】:

    • 我尝试在 Page_Init 中添加控件的重新创建。我添加了逻辑 if(Page.IsPostBack && lvQuestions.Visible) 因此仅在提交表单并实际显示问题时重新创建它们。执行此操作时未找到控件。
    【解决方案2】:

    正如您已经发现的那样,这是一个生命周期问题。尝试在 ListView.ItemCreated 事件而不是 ListView.ItemDataBound 事件中创建动态控件。

    【讨论】:

    • 谢谢 Phaedrus,这成功了!我从来没有读过任何关于在 ItemCreated 事件中创建控件的内容。我将创建移到此处并删除了用于在按钮提交处理程序中重新创建控件的代码块。再次感谢。
    【解决方案3】:

    这对我不起作用,所以我必须在 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();
        }
    

    然后它开始工作了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-09
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多