从动态创建的控件中检索值
本文关键字:检索 控件 动态 创建 | 更新日期: 2023-09-27 18:12:11
我有两个下拉列表,一个用于日期,一个用于夜晚。我还有两个按钮,一个按钮创建动态文本框,客户可以在其中输入他们想要在白天做什么,在他们想要度过夜晚的地方。
。,如果一个客户选择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_Click是按钮的回发方法,例如
即使在后面的代码中添加控件是"好的",它也可能导致以后的麻烦。在编辑视图时,它也不是很好,并且必须在代码隐藏中更改一堆代码。一种解决方案是使用数据绑定控件,例如Repeater控件。这样,您就可以在aspx文件中设计视图,而将编码留给cs-file。在使用回发时,它还负责保存信息,因为它已经设置为使用控件的视图状态,这意味着您不必这样做。
所以,使用一个中继器,你的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>
注意我使用的是一个母版页,所以Content控件只链接到母版页中的一些ContentPlaceHolder。在这个aspx页面中,您将看到重复器控件中的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; }
}
}
}
关于长代码示例,我很抱歉,但我希望它是彻底的。您将看到我在ItemValues属性中引入了一个项列表。您可以从任何需要的地方加载这些值。我使用了Session集合,但如果你想的话,你可以从数据库或其他地方加载。
另外,请注意我们对视图的唯一了解是控件类型和控件ID。没有代码描述控件应该如何添加或样式,我们把它留给aspx页面。这使得两者之间的关注点很容易分离。
相反,当我们想要添加TextBox时,我们添加一个数据项的新实例,一个Item
类的实例。在OnReadValues方法中,我们可以更新绑定到重复器的数据项值,然后使用来自控件的值或来自数据列表中的项的值。
我希望这说明了如何使用ASP。. NET来创建动态页面,而不需要在后面的代码中创建控件,因为如果您这样做的话,实际上不需要它。