首先,我已经看到了大量关于同一问题的帖子,但我不明白的是,当有人回答关于"重新创建页面初始化的控件时,我不会理解这些问题。或者...我有动态创建文本框的代码,但我不确定还需要添加什么。我不完全理解asp.net网络应用的页面生命周期。我用谷歌搜索了这个,我不知道我是否不称职,或者所有答案都是针对比我更了解的人。
请提供您解释的例子。
基本上,用户在文本框中输入#,以获得多少"最喜欢的书籍#34;他们想要保存到数据库中,他/她点击了生成按钮。
行数将填充两个文本框,一个用于标题,一个用于作者。然后我会点击一个按钮,将文本框值保存到数据库中。
我知道这是一个简单的练习,但我是asp.net的新手,这只是我自己想出来的练习,我正在努力学习。我对此有新的设计,但我不想做的一件事是静态创建文本框。谢谢! < 3
这是我的asp.net代码
<form id="form1" runat="server">
<div>
How many favorite books do you have ?
<asp:TextBox ID="TextBox1" runat="server" Width="50px"></asp:TextBox>
<br />
<asp:Button ID="btnBookQty" runat="server" Text="GenerateBooks" OnClick="btnBookQty_Click" />
<br />
<br />
<asp:Panel ID="pnlBooks" runat="server"></asp:Panel>
</div>
</form>
我的c#代码是
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class databasetest_panels_favBookWebsite : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnBookQty_Click(object sender, EventArgs e)
{
int count = Convert.ToInt32(TextBox1.Text);
for (int i = 1; i <= count; i++)
{
TextBox tb = new TextBox();
TextBox tb2 = new TextBox();
tb.Text = "Book " + i.ToString() + " Title";
tb2.Text = "Book " + i.ToString() + " Author";
tb.ID = "TextBoxTitle" + i.ToString();
tb2.ID = "TextBoxAuthor" + i.ToString();
pnlBooks.Controls.Add(tb);
pnlBooks.Controls.Add(tb2);
pnlBooks.Controls.Add(new LiteralControl("<br />"));
}
}
}
答案 0 :(得分:0)
当有人说“你需要跟踪你创建的控件或重新创建它们”时,这意味着你需要将它们存储在postbacks之间。
在ASP.NET中,persistance可以表示Session变量,ViewStates等手段 请参阅此链接http://msdn.microsoft.com/en-us/magazine/cc300437.aspx
创建您创建的文本框列表并将其存储在会话
上private void CreateOrLoadTextBoxes(int numTextBoxes)
{
List<TextBox> lstControls ;
//if its the first time the controls need to be created
if(Session["lstTitleControls"] == null)
{
lstTbTitles = new List<TextBox>(numTextBoxes) ;
lstTbAuthors = new List<TextBox>(numTextBoxes) ;
//create the controls for Book Titles
for (int i = 1; i <= numTextBoxes; i++)
{
TextBox tb = new TextBox();
tb.Text = "Book " + i.ToString() + " Title";
tb.ID = "TextBoxTitle" + i.ToString();
lstTbTitles.Add(tb) ;
}
//Create the controls for Author
for (int i = 1; i <= numTextBoxes; i++)
{
TextBox tb2 = new TextBox();
tb2.Text = "Book " + i.ToString() + " Author";
tb2.ID = "TextBoxAuthor" + i.ToString();
lstTbAuthors.Add(tb2) ;
}
//store the created controls on ViewState asociated with the key "lstTitleControls" and "lstAuthorControls"
// each time you store or access a ViewState you a serialization or deserialization happens which is expensive/heavy
Session["lstTitleControls"] = lstTbTitles ;
Session["lstAuthorControls"] = lstTbAuthors ;
}
else
{
//restore the list of controls from the ViewState using the same key
lstTbTitles = (List<TextBox>) Session["lstTitleControls"];
lstTbAuthors = (List<TextBox>) Session["lstAuthorControls"];
numTextBoxes = lstTbTitles.Count() ;
}
//at this moment lstTbTitles and lstTbAuthors has a list of the controls that were just created or recovered from the ViewState
//now add the controls to the page
for (int i = 1; i <= numTextBoxes; i++)
{
pnlBooks.Controls.Add(lstTbTitles[i]);
pnlBooks.Controls.Add(lstTbAuthors[i]);
pnlBooks.Controls.Add(new LiteralControl("<br />"));
}
}
protected void Page_Load(object sender, EventArgs e)
{
CreateOrLoadTextBoxes(10) ;
}
正如您所注意到我正在使用固定值10调用CreateOrLoadTextBoxes
由您决定使用此代码从文本框中获取值并根据需要调用
答案 1 :(得分:0)
您实际上不需要跟踪以编程方式或动态添加的控件。确实,不知何故有人必须跟踪它们,但是你不应该这样做。
了解ASP.NET Web窗体中的页面生命周期对于任何ASP.NET开发人员来说都是必须的。如果您真正了解页面的基础机制,迟早会遇到这类问题,这些问题会大大简化。
每次向服务器发出请求时,必须从头开始组装整个页面。您可以在Web上阅读(请执行)构成ASP.NET页面的页面生命周期的许多步骤或阶段,但是您可以大致了解其工作原理:
注意:如果你真的认真对待这个问题,你可以在这里从这个人那里学到很多东西:Understanding ASP.NET View State
现在你需要记住的是:为了让动态生成的控件在提交表单后通过点击此按钮将“数据”“粘合”到控件的状态Then I would have a button they click that would save the textbox values into the database.
,您需要在每次往返服务器时将控件添加到页面中。
建议的方法是Page_Init
,因为它来自 LoadViewsate 和 LoadPostData 阶段,其中填充了控件的状态。
但是,在您的情况下,在用户填写第一个表单提交中的信息之前,您不知道要添加多少控件。因此,在用户输入所需控件数后,每次页面加载时都需要找到一种方法将控件添加到页面中。
注意:您可以在btnBookQty_Click
上添加控件并正确保留其数据,因为ASP.NET “正在追赶” 关于控件,但这超出了本答案的范围和目的。
Page_Init
事件处理程序中调用该方法。btnBookQty
的点击事件处理程序中,将标记设置为页面用户提供的数字,然后... btnBookQty_Click
内创建动态生成的控件。这是您需要的模板代码。请注意如何在Session中存储HowManyControls
属性以“回忆”回发中的值:
private int HowManyControls {
get
{
if (Session["HowManyControls"] == null) return 0;
else return (int)Session["HowManyControls"];
}
set
{
Session["HowManyControls"] = value;
}
}
protected void Page_Init(object sender, EventArgs e)
{
if (Page.Ispostback && HowManyControls > 0)
{
//generate the controls dynamically
GenerateControls(HowManyControls);
}
}
protected void btnBookQty_Click(object sender, EventArgs e)
{
//get the number of controls to generate dynamically from the user posted values
HowManyControls = Convert.ToInt32(TextBox1.Text);
//generate the controls dynamically
GenerateControls(HowManyControls);
}
protected void btnSaveToDatabase_Click(object sender, EventArgs e)
{
//iterate on the control's collection in pnlBook object.
for (int i = 1; i <= HowManyControls; i++)
{
//save those value to database accessing to the control's properties as you'd regularly do:
TextBox tb = (TextBox)pnlBooks.FindControl("TextBoxTitle" + i.ToString());
TextBox tb2 = (TextBox)pnlBooks.FindControl("TextBoxAuthor" + i.ToString();
//store these values:
tb.Text;
tb2.Text;
}
}
private void GenerateControls(int count)
{
if (count == 0) { return; }
for (int i = 1; i <= count; i++)
{
TextBox tb = new TextBox();
TextBox tb2 = new TextBox();
tb.Text = "Book " + i.ToString() + " Title";
tb2.Text = "Book " + i.ToString() + " Author";
tb.ID = "TextBoxTitle" + i.ToString();
tb2.ID = "TextBoxAuthor" + i.ToString();
pnlBooks.Controls.Add(tb);
pnlBooks.Controls.Add(tb2);
pnlBooks.Controls.Add(new LiteralControl("<br />"));
}
}
修改强>
我忘了在Page_Init期间ViewState不可用。我现在修改了使用Session的答案。