C# 将文本框动态插入中继器并检索其值

C# 将文本框动态插入中继器并检索其值,c#,asp.net,viewstate,repeater,dynamic-controls,C#,Asp.net,Viewstate,Repeater,Dynamic Controls,我有一个从SQL绑定的转发器,包含可编辑和只读元素的混合。单击行上的“编辑”按钮时,可编辑部分应转换为文本框,单击“更新”时,应保存更改 下面是编辑和更新按钮OnClick代码的(非常)简化版本: switch(commandName) { case "Edit": Label1.Visible = false; //hide read-only version PlaceHolder1.Visible = true; //show editing ver

我有一个从SQL绑定的转发器,包含可编辑和只读元素的混合。单击行上的“编辑”按钮时,可编辑部分应转换为文本框,单击“更新”时,应保存更改

下面是编辑和更新按钮OnClick代码的(非常)简化版本:

switch(commandName)
{
    case "Edit":
        Label1.Visible = false; //hide read-only version
        PlaceHolder1.Visible = true; //show editing version

        //Dict1 is Dictionary<string, string> in this example.
        foreach (var key in Dict1)
        {
            //insert a TextBox dynamically into the PlaceHolder
            PlaceHolder1.Controls.Add(new TextBox 
            { 
                ID = "txt" + key, 
                Text = Dict1[key] 
            });
        }
        break;

    case "Update":
        //retrieve user input from dynamically-added TextBoxes
        foreach (var TextBox1 in PlaceHolder1.Controls.Where(c => c.ID.StartsWith("txt")))
        {
            doStuff(TextBox1);
        }

        Label1.Visible = true; //show read-only version
        PlaceHolder1.Visible = false; //hide editing version
        break;
}
开关(commandName)
{
案例“编辑”:
Label1.Visible=false;//隐藏只读版本
占位符1.Visible=true;//显示编辑版本
//在本例中,Dict1是字典。
foreach(Dict1中的var键)
{
//在占位符中动态插入文本框
占位符1.控件.添加(新文本框
{ 
ID=“txt”+键,
Text=Dict1[key]
});
}
打破
案例“更新”:
//从动态添加的文本框中检索用户输入
foreach(占位符1.Controls.Where中的var TextBox1(c=>c.ID.StartsWith(“txt”))
{
doStuff(文本框1);
}
Label1.Visible=true;//显示只读版本
占位符1.Visible=false;//隐藏编辑版本
打破
}
问题是当页面发回时,我动态添加的文本框不存在。我已经检查了调试器中的
placeholder 1.Controls
,其中没有文本框<代码>占位符1本身位于中继器内,但我不会在回发时重新绑定中继器

我曾经考虑过使用原始HTML代替TextBox控件,并从Request.Form中提取值,但我觉得这有点不太妥当。如何使动态添加的文本框在回发中持久化


编辑:

这里有一些复杂的情况,如果没有大量的示例代码就很难显示出来。以下是一些大问题:

  • 中继器中的每个单元格可以混合使用只读和可编辑文本(即动态插入的标签和文本框)
  • 我不知道每个单元格中有多少个可编辑区域。原始文本可能看起来像
    blah blah@A1@blah blah@A2@blah…
    ,我必须插入替换文本来代替@A1@、@A2@,等等。在编辑模式下,只有替换文本是可编辑的

动态添加控件时,它们不会在回发中保留。回发后,您必须再次将它们添加到页面中。我通常在页面加载时这样做。然后,一旦添加了它们,它们的回发状态将在ASP.NET页面生命周期的后期正确恢复

所以

  • 每次加载页面时都必须添加动态控件
  • 但一旦添加它们,ASP.NET将正确恢复它们的状态

希望这有帮助

动态添加控件时,它们不会跨回发保留。回发后,您必须再次将它们添加到页面中。我通常在页面加载时这样做。然后,一旦添加了它们,它们的回发状态将在ASP.NET页面生命周期的后期正确恢复

所以

  • 每次加载页面时都必须添加动态控件
  • 但一旦添加它们,ASP.NET将正确恢复它们的状态

希望这有帮助

一个可能的答案是在项目模板中预定义文本框,然后在单击事件中为给定行设置其“可见性”

第二种可能是重构中继器以使用GRIDVIEW控件。它支持开箱即用的可编辑模板

无论如何,现在的情况是,由于这些控件是动态添加的,所以在下一次回发时不会重新创建它们。在回发中,如果要访问这些控件,则需要重新创建它们但是,不要忘记该值存储在表单集合中:

myval =  request.form["txt" + key];

一个可能的答案是在项目模板中预定义文本框,然后在单击事件中为给定行设置其“可见性”

第二种可能是重构中继器以使用GRIDVIEW控件。它支持开箱即用的可编辑模板

无论如何,现在的情况是,由于这些控件是动态添加的,所以在下一次回发时不会重新创建它们。在回发中,如果要访问这些控件,则需要重新创建它们但是,不要忘记该值存储在表单集合中:

myval =  request.form["txt" + key];

顺便说一下,这是非常简化的示例代码。实际上我并没有给控件命名,比如
Label1
。顺便说一句,这是非常简化的示例代码。实际上,我没有给控件命名,比如
Label1
。这可能会很复杂,因为在中继器绑定之前,我不知道有多少控件。如果我重新绑定中继器,输入的值会丢失吗?正如您所建议的,我通过在页面加载期间添加文本框而不是编辑按钮的OnClick事件来解决问题。谢谢你的帮助!这可能很复杂,因为在中继器绑定之前,我不知道有多少控件。如果我重新绑定中继器,输入的值会丢失吗?正如您所建议的,我通过在页面加载期间添加文本框而不是编辑按钮的OnClick事件来解决问题。谢谢你的帮助!请求。表单想法是一个好主意。不知怎的,我只是想把它用于普通的HTML输入。但是我不需要知道每个文本框的客户ID吗?在这种情况下,我必须在某个地方捕获ItemIndex。是的(除非在占位符中使用标准html控件)。但是,您可以始终使用LINQ根据已知字符串查询集合(类似于您使用“txt”的方式,只需将其称为“myrptrText”作为前缀或其他名称,非常感谢您的帮助。在页面加载期间构建文本框这一次似乎已经做到了这一点,但对于f