C# 从asp.net中动态创建的文本框中获取文本

C# 从asp.net中动态创建的文本框中获取文本,c#,asp.net,.net,dynamic,controls,C#,Asp.net,.net,Dynamic,Controls,我整个上午都在忙这个,希望能得到一些帮助。从本质上说,我在.NET4中动态创建的一些textbox控件中获取值时遇到了问题 下面是所需的应用程序流程 1) 。用户从一个下拉菜单中选择一个html文档,它是一封信的模板。此html文档具有格式为$VARIABLENAME$的标记,这些标记将替换为正确的值 2) 。该程序在模板中运行,提取$STRING$格式的所有字符串,并将它们存储在列表中 3) 。对于此列表中的每个条目,程序将基于原始$VARIABLENAME$字段生成一个asp:label和一

我整个上午都在忙这个,希望能得到一些帮助。从本质上说,我在.NET4中动态创建的一些textbox控件中获取值时遇到了问题

下面是所需的应用程序流程

1) 。用户从一个下拉菜单中选择一个html文档,它是一封信的模板。此html文档具有格式为$VARIABLENAME$的标记,这些标记将替换为正确的值

2) 。该程序在模板中运行,提取$STRING$格式的所有字符串,并将它们存储在列表中

3) 。对于此列表中的每个条目,程序将基于原始$VARIABLENAME$字段生成一个asp:label和一个具有唯一ID的asp:textbox

4) 。用户输入替换值,然后点击提交

5) 。程序用替换值替换所有$STRING$,并输出结果

在我需要从文本框中获取值之前,一切都运行良好。我很确定这是页面生命周期的一个问题,但是因为文本框在用户从下拉列表中选择所需模板之前不会生成,所以我不确定如何使它们在回发过程中保持不变,以便我可以引用它们

我这样做完全错了吗?submitbutton事件发生回发后,如何访问从下拉事件创建的文本字段

编辑: 以下是大部分相关代码

protected void createTextBoxes(List<string> results)
    {
        if (results != null)
        {
            foreach (string result in results)
            {
                string formattedResult = result.Substring(1, result.Length - 2);
                formattedResult = formattedResult.ToLower();
                formattedResult = char.ToUpper(formattedResult[0]) + formattedResult.Substring(1);


                var label = new Label();
                label.ID = formattedResult;
                label.Text = formattedResult + ": ";
                templateFormPlaceholder.Controls.Add(label);

                var textBox = new TextBox();
                textBox.ID = result;
                templateFormPlaceholder.Controls.Add(textBox);
                templateFormPlaceholder.Controls.Add(new LiteralControl("<br />"));

                previewBtn.Visible = true;
            }
        }
    }

protected void templateDD_SelectedIndexChanged(object sender, EventArgs e)
    {
        var templatePath = "";
        if (templateDD.SelectedIndex == 0)
        {
            previewBtn.Visible = false;
        }

        if (templateDD.SelectedIndex == 1)
        {
            templatePath = employeePath;
        }
        else if (templateDD.SelectedIndex == 2)
        {
            templatePath = managerPath;
        }
        List<string> regMatches = FindMatches(templatePath);
        Session["regMatches"] = regMatches;
        createTextBoxes(regMatches);
    }

protected void Page_Init(object sender, EventArgs e)
    {
        if (Session["regMatches"] != null)
        {
            createTextBoxes((List<string>)Session["regMatches"]);
        }
    }
受保护的void createTextBox(列出结果)
{
如果(结果!=null)
{
foreach(结果中的字符串结果)
{
string formattedResult=result.Substring(1,result.Length-2);
formattedResult=formattedResult.ToLower();
formattedResult=char.ToUpper(formattedResult[0])+formattedResult.Substring(1);
var label=新标签();
label.ID=格式化结果;
label.Text=formattedResult+“:”;
templateFormPlaceholder.Controls.Add(标签);
var textBox=新的textBox();
textBox.ID=结果;
templateFormPlaceholder.Controls.Add(文本框);
templateFormPlaceholder.Controls.Add(新的LiteralControl(“
”); previewBtn.Visible=true; } } } 受保护的无效模板dd_SelectedIndexChanged(对象发送方,事件参数e) { var templatePath=“”; 如果(templateDD.SelectedIndex==0) { previewBtn.Visible=false; } 如果(templateDD.SelectedIndex==1) { templatePath=employeePath; } else if(templateDD.SelectedIndex==2) { templatePath=managerPath; } List regMatches=FindMatches(templatePath); 会话[“regMatches”]=regMatches; 创建文本框(regMatches); } 受保护的无效页_Init(对象发送方,事件参数e) { if(会话[“regMatches”]!=null) { CreateTextBox((列表)会话[“regMatches”]); } }
稍后,我将尝试将这些文本框中的值添加到字典中。参数是字典的名称。关键字段是$STRING$,结果是用户在文本框中输入的内容

   protected void previewBtn_Click(object sender, EventArgs e)
    {
        List<string> matchResults = (List<string>)Session["regMatches"];
        Dictionary<string, string> parameters = new Dictionary<string, string>();
        foreach (string result in matchResults)
        {
            TextBox tb = (TextBox)templateFormPlaceholder.FindControl(result);
            parameters.Add(result, tb.Text);
        }

        var template = ReplaceKeys(parameters);
        outputLBL.Text = template;
protectedvoid previewBtn\u单击(对象发送方,事件参数e)
{
列表匹配结果=(列表)会话[“regMatches”];
字典参数=新字典();
foreach(匹配结果中的字符串结果)
{
TextBox tb=(TextBox)templateFormPlaceholder.FindControl(结果);
添加(结果,tb.Text);
}
变量模板=替换键(参数);
outputLBL.Text=模板;
这是.aspx代码

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="offerLetter.aspx.cs"     Inherits="templateRegexTesting.offerLetter" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
    <p>
        Which template would you like to use?
    </p>
    <asp:DropDownList ID="templateDD" runat="server" OnSelectedIndexChanged="templateDD_SelectedIndexChanged"
        AutoPostBack="true">
        <asp:ListItem></asp:ListItem>
        <asp:ListItem Value="1">Employee</asp:ListItem>
        <asp:ListItem Value="2">Manager</asp:ListItem>
    </asp:DropDownList>
    <br />
    <asp:PlaceHolder ID="templateFormPlaceholder" runat="server" />
    <div>
        <asp:Button ID="previewBtn" runat="server" Text="Preview" Visible="false" OnClick="previewBtn_Click" />
    </div>
    <div>
        <asp:Label ID="outputLBL" runat="server"></asp:Label>
    </div>
    <br />
</div>
</form>
</body>
</html>


您希望使用哪个模板?

雇员 经理

编辑:当我想出来的时候,我把它放在了一个评论中,但我想我应该把它移到问题中,这样它就更明显了:


我想我应该更新这个。我觉得自己有点傻,但我确实做到了。基本上,我给控件分配了一个等同于替换令牌的ID(例如,ID=“$FIRSTNAME$)。我甚至不知道$会引起任何问题。当我刚改成ID=“FIRSTNAME”格式时它工作得很好。感谢您的所有帮助!

您说得对,这是关于页面生命周期的问题。动态创建的控件必须在
页面初始化阶段重新创建,以便在viewstate绑定阶段之前存在。这意味着必须以某种方式(可能使用
会话
)存储您在上一次处理中创建的用于重新创建的
文本框的数量。提醒使用相同的ID,并将它们添加到您的控制树(中继器或您正在使用的其他东西)


更新

让我给你一个建议: 1.声明类型为
List
(我们称之为
createdTextBox
)的类属性

  • 声明一个方法,该方法接收创建文本框所需的任何内容。此方法不能读取超出其范围的任何内容。它只需接收一些参数,创建文本框并将它们添加到另一个控件(例如
    中继器
    )。将创建的每个文本框添加到
    CreatedTextBox

  • 在下拉更改事件中,读取选项,将其保存到
    会话
    并调用此方法

  • Page\u Init
    上,在
    会话中验证该对象。如果该对象为null或空,则不执行任何操作。如果该对象有值,则调用相同的方法,并传递相同的参数

  • 当需要从动态创建的文本框中检索时,请使用
    createdTextBox
    <div class="form-group">
    <asp:Panel ID="panel" runat="server" CssClass="form-group">
    
    </asp:Panel>
    </div>
    
     protected void create_dynamic_text(object sender, EventArgs e)
    {
        int num = 5; // you can give the number here
        for (int i = 0; i < num;i++ )
        {
            TextBox tb = new TextBox();
            tb.ID = "txt_box_name" + i.ToString();
            tb.CssClass = "add classes if you need";
            tb.Width = 400; //Manage width and height 
            panel.Controls.Add(tb); //panel is my ASP.Panel object. Look above for the design code of ASP panel
        }
    }
    
     protected void reade_values(object sender, EventArgs e)
    {
       int num=5; // your count goes here
        TextBox tb = new TextBox();
            for (int i = 0; i < num; i++)
            {
               tb=(TextBox)panel.FindControl("txt_box_name"+i.ToString());
               string value = tb.Text; //You have the data now
            }
        }
    }