从动态创建的asp.net文本框中将数据保存到数据库

时间:2013-12-27 00:21:58

标签: c# asp.net textbox dynamic-controls

首先,我已经看到了大量关于同一问题的帖子,但我不明白的是,当有人回答关于"重新创建页面初始化的控件时,我不会理解这些问题。或者...我有动态创建文本框的代码,但我不确定还需要添加什么。我不完全理解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 />"));

    } 
}

}

2 个答案:

答案 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页面的页面生命周期的许多步骤或阶段,但是您可以大致了解其工作原理:

  • 发出请求时,将解析.aspx文件并从中创建内存源代码。此阶段称为 Instantiation 阶段,此时将创建页面的控件层次结构。
  • 之后,页面将进入初始化阶段,其中会触发页面的Init事件。这是动态添加控件的“地方”。
  • 接下来是
  • LoadViewState 阶段。此时,作为页面控件层次结构一部分的控件的信息会更新其“状态”,以使它们返回到回发之前的状态。 (这个阶段不会在第一次访问页面时发生,它只是一个回发阶段。)
  • LoadPostData 阶段是指将已过帐到服务器的数据(通过提交表单)加载到控件中。初学者ASP.NET开发人员几乎不知道这个阶段,因为他们认为ASP.NET引擎自动强制执行的所有“状态保存”都来自神奇的Viewstate。

注意:如果你真的认真对待这个问题,你可以在这里从这个人那里学到很多东西: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 “正在追赶” 关于控件,但这超出了本答案的范围和目的。

  1. 添加一个私有字段作为布尔标志,并指示要添加的控件数。
  2. 创建一个私有方法,将控件添加到页面中,将要添加的控件数作为参数。
  3. 只有在标志指示必须添加某些字段时,才从Page_Init事件处理程序中调用该方法。
  4. btnBookQty的点击事件处理程序中,将标记设置为页面用户提供的数字,然后...
  5. 调用方法以从btnBookQty_Click内创建动态生成的控件。
  6. 这是您需要的模板代码。请注意如何在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的答案。