C# 从动态创建的控件中检索值

C# 从动态创建的控件中检索值,c#,asp.net,C#,Asp.net,我有两个下拉列表,一个是白天的,一个是晚上的。我还有两个按钮,一个按钮创建动态文本框,客户可以在其中输入他们白天想做的事情,以及他们想在哪里过夜 e、 例如,如果一位客户选择了4天4夜,则按第一个按钮将创建一个文本框 当用户单击第二个按钮时,我想将所有这些值存储在数据库中,但我注意到在回发时字段丢失,并且我没有要存储的数据 如何在回发时从运行时创建的控件中获取值?以下是您的方法: protected void Page_Load(object sender, EventArgs e) {

我有两个下拉列表,一个是白天的,一个是晚上的。我还有两个按钮,一个按钮创建动态文本框,客户可以在其中输入他们白天想做的事情,以及他们想在哪里过夜

e、 例如,如果一位客户选择了4天4夜,则按第一个按钮将创建一个文本框

当用户单击第二个按钮时,我想将所有这些值存储在数据库中,但我注意到在回发时字段丢失,并且我没有要存储的数据


如何在回发时从运行时创建的控件中获取值?

以下是您的方法:

 protected void Page_Load(object sender, EventArgs e)
 {
    if (Session["testTextBox"] != null)
    {
        Request.Form[Session["testTextBox"].ToString()].ToString()
    }
 }

 protected void Button1_Click(object sender, EventArgs e)
 {
    TextBox t = new TextBox { ID = "testTextBox" };
    this.Form.Controls.Add(t);
    Session["testTextBox"] = t.UniqueID;
 }

如果通过客户端调用添加文本框,则不需要存储UniqueID。例如,Button1\u Click是按钮的回发方法。

尽管在代码隐藏中添加控件“很好”,但以后可能会出现问题。在编辑视图时,它也不是很好,您必须在代码隐藏中更改一堆代码。解决方案是使用数据绑定控件,例如中继器控件。这样,您就可以在aspx文件中设计视图,并将编码留给cs文件。它还负责在使用回发时保存信息,因为它已经设置为使用控件的viewstate,这意味着您不必这样做

因此,使用中继器,您的aspx可以看起来像这样

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="RepeaterPage.aspx.cs" Inherits="ASPTest.RepeaterPage" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h1>Test</h1>
    <div>
        <asp:Button Text="Add textbox" ID="Button1" OnClick="OnAddItem" runat="server" />
        <asp:Button Text="Read values" ID="Button2" OnClick="OnReadValues" runat="server" />
    </div>
    <div>
        <asp:Label ID="values" runat="server"></asp:Label>
    </div>
    <asp:Repeater ID="listofvalues" runat="server">
        <ItemTemplate>
            <asp:HiddenField ID="ID" Value='<%# Eval("ID") %>' runat="server" />
            <asp:TextBox ID="ValueBox" Text='<%# Server.HtmlEncode((string)Eval("Value")) %>' runat="server" />
        </ItemTemplate>
    </asp:Repeater>
</asp:Content>

试验
请注意,我使用的是母版页,因此内容控件仅链接到母版页中的某个ContentPlaceHolder。在这个aspx页面中,您将看到repeater控件中的itemtemplate设置了显示值所需的所有设计。我们将在代码中看到这是如何实现的

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ASPTest
{
    public partial class RepeaterPage : Page
    {
        private List<Item> cache;
        public List<Item> ItemValues
        {
            get
            {
                if (cache != null)
                {
                    return cache;
                }
                // load values from database for instance
                cache = Session["values"] as List<Item>;
                if (cache != null)
                {
                    return cache;
                }
                Session["values"] = cache = new List<Item>();
                return cache;
            }
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            listofvalues.DataBinding += bindValues;
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (!Page.IsPostBack)
            {
                DataBind();
            }
        }

        protected void OnAddItem(object sender, EventArgs e)
        {
            ItemValues.Add(new Item("some value"));
            DataBind();
        }

        protected void OnReadValues(object sender, EventArgs e)
        {
            foreach (RepeaterItem repeateritem in listofvalues.Items)
            {
                TextBox box = (TextBox)repeateritem.FindControl("ValueBox");
                HiddenField idfield = (HiddenField)repeateritem.FindControl("ID");
                Item item = findItem(idfield.Value);
                item.Value = box.Text;
            }
            StringBuilder builder = new StringBuilder();
            foreach (Item item in ItemValues)
            {
                builder.Append(item.Value).Append(";");
            }
            values.Text = builder.ToString();
        }

        private Item findItem(string idvalue)
        {
            Guid guid = new Guid(idvalue);
            foreach (Item item in ItemValues)
            {
                if (item.ID == guid)
                {
                    return item;
                }
            }
            return null;
        }

        private void bindValues(object sender, EventArgs e)
        {
            listofvalues.DataSource = ItemValues;
        }
    }

    public class Item
    {
        private readonly Guid id;
        private string value;

        public Item(string value)
        {
            this.value = value;
            id = Guid.NewGuid();
        }

        public Guid ID
        {
            get { return id; }
        }

        public string Value
        {
            get { return value; }
            set { this.value = value; }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统文本;
使用System.Web.UI;
使用System.Web.UI.WebControl;
命名空间ASPTest
{
公共部分类重复页面:第页
{
私有列表缓存;
公共列表项值
{
得到
{
if(缓存!=null)
{
返回缓存;
}
//从数据库加载实例的值
缓存=会话[“值”]作为列表;
if(缓存!=null)
{
返回缓存;
}
会话[“值”]=缓存=新列表();
返回缓存;
}
}
受保护的覆盖无效OnInit(事件参数e)
{
碱基.奥尼特(e);
listofvalues.DataBinding+=bindValues;
}
受保护的覆盖无效加载(事件参数e)
{
基础荷载(e);
如果(!Page.IsPostBack)
{
数据绑定();
}
}
受保护的附加项无效(对象发送方、事件参数e)
{
添加(新项目(“某些值”);
数据绑定();
}
受保护的void OnReadValues(对象发送方、事件参数e)
{
foreach(listofvalues.Items中的RepeaterItem RepeaterItem)
{
TextBox=(TextBox)repeateritem.FindControl(“ValueBox”);
HiddenField idfield=(HiddenField)repeateritem.FindControl(“ID”);
Item Item=findItem(idfield.Value);
item.Value=box.Text;
}
StringBuilder=新的StringBuilder();
foreach(ItemValues中的项)
{
builder.Append(item.Value).Append(“;”);
}
values.Text=builder.ToString();
}
私有项findItem(字符串idvalue)
{
Guid=新的Guid(idvalue);
foreach(ItemValues中的项)
{
如果(item.ID==guid)
{
退货项目;
}
}
返回null;
}
私有void bindValues(对象发送方、事件参数)
{
listofvalues.DataSource=ItemValues;
}
}
公共类项目
{
私有只读Guid id;
私有字符串值;
公共项(字符串值)
{
这个值=值;
id=Guid.NewGuid();
}
公共Guid ID
{
获取{return id;}
}
公共字符串值
{
获取{返回值;}
设置{this.value=value;}
}
}
}
对于冗长的代码示例,我很抱歉,但我希望它是彻底的。您将看到我在ItemValues属性中引入了一个项目列表。可以从任意位置加载值。我使用了会话集合,但如果需要,可以从数据库或其他地方加载

另外,请注意,我们对视图的唯一了解是控件类型和控件ID。没有代码描述如何添加控件或设置控件样式,我们将其留给aspx页面。这使得两者之间的关注点容易分离

相反,当我们想要添加一个文本框时,我们会添加一个数据项的新实例,
item
类的实例。在OnReadValues方法中,我们可以更新绑定到中继器的数据项值,然后使用控件中的值或数据列表中的项中的值


我希望这说明了如何使用ASP.NET创建动态页面,而无需在代码隐藏中创建控件,因为这样做实际上并不需要它。

如何创建动态文本框?Javascript,CodebehindIn为了让我们帮助您,您必须发布您的代码。请粘贴您的页面\加载事件…您需要查看表单控件集合。你能发布一些代码片段吗?有两个按钮,如果用户客户端在1上,则会创建一个文本框,在bu上
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="RepeaterPage.aspx.cs" Inherits="ASPTest.RepeaterPage" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h1>Test</h1>
    <div>
        <asp:Button Text="Add textbox" ID="Button1" OnClick="OnAddItem" runat="server" />
        <asp:Button Text="Read values" ID="Button2" OnClick="OnReadValues" runat="server" />
    </div>
    <div>
        <asp:Label ID="values" runat="server"></asp:Label>
    </div>
    <asp:Repeater ID="listofvalues" runat="server">
        <ItemTemplate>
            <asp:HiddenField ID="ID" Value='<%# Eval("ID") %>' runat="server" />
            <asp:TextBox ID="ValueBox" Text='<%# Server.HtmlEncode((string)Eval("Value")) %>' runat="server" />
        </ItemTemplate>
    </asp:Repeater>
</asp:Content>