如何获取动态填充控件的值

R R*_*R R 26 c# asp.net

我在aspx页面中有一个div Conatining a Panel

<div id="divNameofParticipants" runat="server">
    <asp:Panel ID="panelNameofParticipants" runat="server">
    </asp:Panel>
</div>
Run Code Online (Sandbox Code Playgroud)

我使用以下代码从代码隐藏动态填充面板:

void btnSubmitCountParticipant_Click(object sender, EventArgs e)
    {
        StringBuilder sbparticipantName=new StringBuilder();

        try
        {
            int numberofparticipants = Convert.ToInt32(drpNoofparticipants.SelectedValue);
            ViewState["numberofparticipants"] = numberofparticipants;
            Table tableparticipantName = new Table();
            int rowcount = 1;
            int columnCount = numberofparticipants;
            for (int i = 0; i < rowcount; i++)
            {
                TableRow row = new TableRow();
                for (int j = 0; j < columnCount; j++)
                {
                    TableCell cell = new TableCell();
                    TextBox txtNameofParticipant = new TextBox();
                    txtNameofParticipant.ID = "txtNameofParticipant" + Convert.ToString(i);
                    cell.ID = "cell" + Convert.ToString(i);
                    cell.Controls.Add(txtNameofParticipant);
                    row.Cells.Add(cell);


                }
                tableparticipantName.Rows.Add(row);
                panelNameofParticipants.Controls.Add(tableparticipantName);

            }

        }
        catch(Exception ex)
        {


        }
    }
Run Code Online (Sandbox Code Playgroud)

现在我想在codebehind.for中访问这些动态生成的文本框的值,我的代码如下:

public void CreateControls()
    {

        try
        {
            //String test1 = test.Value;
            List<string> listParticipantName = new List<string>();
            if (ViewState["numberofparticipants"] != null)
            {
                int numberofparticipants = Convert.ToInt32(ViewState["numberofparticipants"]);
                for (int i = 0; i < numberofparticipants; i++)
                {
                    string findcontrol = "txtNameofParticipant" + i;
                    TextBox txtParticipantName = (TextBox)panelNameofParticipants.FindControl(findcontrol);
                    listParticipantName.Add(txtParticipantName.Text);

                }
            }
        }
        catch (Exception ex)
        {

        }
    }
Run Code Online (Sandbox Code Playgroud)

但我无法获得代码隐藏中的值.

 TextBox txtParticipantName = (TextBox)panelNameofParticipants.FindControl(findcontrol);
Run Code Online (Sandbox Code Playgroud)

上面的代码无法找到控件,它总是给出null.我做错了.我在页面加载中重新创建了控件,因为回发是无状态但仍然没有成功.

提前致谢

Ken*_*per 7

您需要在PreInit中创建不在OnLoad中的动态控件.请参阅此处的文档:https://msdn.microsoft.com/en-us/library/ms178472.aspx

重新/在页面加载时创建控件将导致ViewState不被绑定到控件,因为viewnate绑定在OnLoad之前发生.


Bin*_*nke 6

正如其他人所说.要创建动态控件,您需要为每个回发和正确的时间执行此操作.要呈现动态控件,请使用Preinit事件.我建议您查看https://msdn.microsoft.com/en-us/library/ms178472(v=vs.80).aspx以了解更多相关信息.

MSDN - PreInit: 使用此事件执行以下操作:检查IsPostBack属性以确定这是否是第一次处理页面. 创建或重新创建动态控件. 动态设置母版页.动态设置Theme属性.读取或设置配置文件属性值.注意注意如果请求是回发,则控件的值尚未从视图状态恢复.如果在此阶段设置控件属性,则其值可能会在下一个事件中被覆盖.

下一个有趣的事件是Preload,它指出:

MSDN - PreLoad 如果需要在Load事件之前对页面或控件执行处理,请使用此事件. 页面引发此事件后,它会为自身和所有控件加载视图状态,然后处理Request实例中包含的所有回发数据.

这意味着在下一个事件Load(Page_Load)中应该加载视图状态,所以在这里你应该能够有效地检查你的值.

您还需要确保启用了视图状态,最简单的可能是在页面级指令中:

<%@Page EnableViewState="True" %>
Run Code Online (Sandbox Code Playgroud)

看看文章https://msdn.microsoft.com/en-us/library/ms972976.aspx 2,它更深入地介绍了这一切

注意

如果您的问题是需要在按钮单击时动态创建控件,并且将创建许多控件,您应该转向jQuery ajax并在代码后面的公共函数上使用属性[WebMethod].创建动态控件和维护ViewState非常昂贵,所以我真的推荐这个,以获得更好的用户体验.


nav*_*een 5

如果您使用DataPresentation控件asp:GridView就会更容易.

标记

<asp:GridView ID="ParticipantsGrid" runat="server" AutoGenerateColumns="false">   
    <Columns>
        <asp:TemplateField HeaderText="Participants">
            <ItemTemplate>
                <asp:TextBox ID="txtNameofParticipant" runat="server" 
                    Text='<%# Container.DataItem %>'>
                </asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
Run Code Online (Sandbox Code Playgroud)

代码隐藏

protected void btnSubmitCountParticipant_Click(object sender, EventArgs e)
{
    try
    {
        var selectedParticipantCount = Convert.ToInt32(drpNoofparticipants.SelectedValue);
        var items = Enumerable.Repeat(string.Empty, selectedParticipantCount).ToList();
        ParticipantsGrid.DataSource = items;
        ParticipantsGrid.DataBind();
    }
    catch (Exception ex)
    { }
}
public void CreateControls()
{

    try
    {
        var participants = ParticipantsGrid.Rows
            .Cast<GridViewRow>()
            .Select(row => ((TextBox)row.FindControl("txtNameofParticipant")).Text)
            .ToList();
    }
    catch (Exception ex)
    { }
}
Run Code Online (Sandbox Code Playgroud)