如何从c#中动态创建的下拉列表创建动态文本框

时间:2015-03-22 16:33:34

标签: c# asp.net

我想创建动态文本框的数量(在下拉列表中选择的值从1到5不等)

注意:下拉列表列表也是动态创建的控件

此处示例代码:

    Table table=new Table();

    for (int i = 1; i <= 5; i++)
    {
        TableRow row = new TableRow();
        TableCell cell = new TableCell();

        DropDownList drp_splzn = new DropDownList();

        drp_splzn.ID = i.ToString();
        drp_splzn.Items.Add("-SELECT SPECIALIZATION-");
        drp_splzn.Items.Add(new ListItem("1", "1"));
        drp_splzn.Items.Add(new ListItem("2", "2"));
        drp_splzn.Items.Add(new ListItem("3", "3"));
        drp_splzn.Items.Add(new ListItem("4", "4"));
        drp_splzn.Items.Add(new ListItem("5", "5"));


        cell.Controls.Add(drp_splzn);

        row.Cells.Add(cell);
        table.Rows.Add(row);
    }

我希望创建文本框,然后创建受尊重的下拉列表...我知道可能使用回发和下拉列表更改事件...但我无法弄清楚

3 个答案:

答案 0 :(得分:1)

这是最终问题的解决方案。

下图是插图(您可以更改文本框内容,新值将保留在回发之间):

many selections

我们现在面临着保留已经显示的文本框 displayed以及保留其所持有的值的需求。 T 他这样做的关键是使用ViewState对象。我们将通过在每个我们希望其状态持久化的控件上启用它来实现这一点。另一方面,ASP .NET的引擎不会为我们重新创建控件,但是当它们可用时它将使用ViewState反对他们的机制。

首先让我们创建一个Dictionary对象。我们将使用它来保存两个信息。 1号used下拉列表,2号selected value on that dropdownlist。我们将它创建为静态变量,就像我们使用boolean hasDropDowns

一样
public partial class WebForm1 : System.Web.UI.Page
{
    static bool hasDropDowns = false;
    static Dictionary<int, int> textBoxesStateDictionnary = new Dictionary<int, int>();

...

我们将使用下拉列表的id作为键,并将该下拉列表中的选定值用作关联值。

然后我们需要更改selectindex更改的事件处理程序。当选择一个值并创建文本框时,我们需要在Dictionary中添加一个新条目。这是selectindex已更改事件处理程序的新版本

 void drp_splzn_SelectedIndexChanged(object sender, EventArgs e)
    {

        DropDownList chosenDropDown = (DropDownList)sender;

        Int32 pickedValue = Int32.Parse(chosenDropDown.SelectedValue);

        Table table = // new Table();
         (Table)Page.Form.FindControl("table" + chosenDropDown.ID);

        for (int i = 0; i < pickedValue; i++)
        {

            TableRow row = new TableRow();
            TableCell cell = new TableCell();
            cell.Attributes.Add("runat", "server");

            TextBox txt_splzn = new TextBox();

            txt_splzn.ID = "txtB_" + chosenDropDown.ID + "_" + i.ToString();
            txt_splzn.Text = "Text Number " + i.ToString();
            txt_splzn.EnableViewState = true;

            cell.Controls.Add(txt_splzn);

            row.Cells.Add(cell);
            table.Rows.Add(row);

        }

        textBoxesStateDictionnary.Add(Int32.Parse(chosenDropDown.ID), Int32.Parse(chosenDropDown.SelectedValue));

    }

正如您在最后一行代码中看到的那样,关键是所选下拉列表的ID和相应的值,它是选定的值。

此外,我们必须更改文本框ID,因为之前的ID是由litteral和选定的值组成的。如果我们保持相同,Page.Form.FindControl方法会引发异常:ID是唯一的。

现在我们需要影响Page_Load事件处理程序。在我们重新创建下拉列表之后,我们会查看字典以查看是否有相应的条目(使用它的ID)。如果有,我们重新创建尽可能多的文本框,如字典条目中的相应值所示。然后我们相信ViewState可以正常工作,因为当我们创建文本框时,我们激活了ViewState(参见txt_splzn.EnableViewState = true;

这是Page_Load事件处理程序的代码

 protected void Page_Load(object sender, EventArgs e)
    {

        if (Page.IsPostBack)
        {
            if (!hasDropDowns)
            {
                return;
            }

            Table table = new Table();

            for (int i = 1; i <= 5; i++)
            {
                TableRow row = new TableRow();
                TableCell cell = new TableCell();
                cell.Attributes.Add("runat", "server");

                DropDownList drp_splzn = new DropDownList();

                drp_splzn.ID = i.ToString();
                drp_splzn.Items.Add("-SELECT SPECIALIZATION-");
                drp_splzn.Items.Add(new ListItem("1", "1"));
                drp_splzn.Items.Add(new ListItem("2", "2"));
                drp_splzn.Items.Add(new ListItem("3", "3"));
                drp_splzn.Items.Add(new ListItem("4", "4"));
                drp_splzn.Items.Add(new ListItem("5", "5"));

                drp_splzn.SelectedIndexChanged += drp_splzn_SelectedIndexChanged;
                drp_splzn.AutoPostBack = true;
                drp_splzn.EnableViewState = true;


                cell.Controls.Add(drp_splzn);

                row.Cells.Add(cell);
                table.Rows.Add(row);

                TableRow rowT = new TableRow();
                TableCell cellT = new TableCell();
                cellT.Attributes.Add("runat", "server");

                Table table2 = new Table();

                table2.ID = "table" + i.ToString();


                int retrievedValue = -1;
                if (textBoxesStateDictionnary.TryGetValue(i, out retrievedValue))
                {
                    for (int j = 0; j < retrievedValue; j++)
                    {
                        // Recreate them
                        TableRow rowTT = new TableRow();
                        TableCell cellTT = new TableCell();
                        cellTT.Attributes.Add("runat", "server");

                        TextBox txt_splzn = new TextBox();

                        txt_splzn.ID = "txtB_" + i +"_" + j.ToString();

                        txt_splzn.EnableViewState = true;

                        cellTT.Controls.Add(txt_splzn);
                        rowTT.Controls.Add(cellTT);
                        table2.Controls.Add(rowTT);

                    }

               }

                cellT.Controls.Add(table2);

                rowT.Cells.Add(cellT);
                table.Rows.Add(rowT);
            }

            this.Controls.Add(table);

            Page.Form.Controls.Add(table);

        }
        else
        {

        }

    }

就是这样。

答案 1 :(得分:0)

我了解您已动态添加下拉列表,并且您希望根据下拉列表中的选定值创建文本框

首先,我添加了一个按钮,在单击按钮

后动态创建DropDownlist对象
 <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Make DropDowns" />

然后我在Button_Click处理程序事件中创建了DropDownlist(只需双击这个静态的按钮就可以创建这个事件处理程序)

我在这个处理程序中所做的就是使用你的下拉列表创建代码,然后在页面控件中添加表格的表单对象。 否则,您会收到一条错误消息,告知您需要将其置于runat = server之内。

我也使用静态布尔变量,它允许我保留DropDownlist已创建的信息

以下是此事件的处理程序代码

 protected void Button1_Click(object sender, EventArgs e)
    {

        Table table = new Table();

        for (int i = 1; i <= 5; i++)
        {
            TableRow row = new TableRow();
            TableCell cell = new TableCell();
            cell.Attributes.Add("runat", "server");

            DropDownList drp_splzn = new DropDownList();

            drp_splzn.ID = i.ToString();
            drp_splzn.Items.Add("-SELECT SPECIALIZATION-");
            drp_splzn.Items.Add(new ListItem("1", "1"));
            drp_splzn.Items.Add(new ListItem("2", "2"));
            drp_splzn.Items.Add(new ListItem("3", "3"));
            drp_splzn.Items.Add(new ListItem("4", "4"));
            drp_splzn.Items.Add(new ListItem("5", "5"));

            drp_splzn.SelectedIndexChanged += drp_splzn_SelectedIndexChanged;
            drp_splzn.AutoPostBack = true ;
            drp_splzn.EnableViewState = true;


            cell.Controls.Add(drp_splzn);

            row.Cells.Add(cell);
            table.Rows.Add(row);
        }

        this.Controls.Add(table);

        Page.Form.Controls.Add(table);
        hasDropDowns = true;
    }

所以我的布尔变量名为hasDropDowns,并且在添加下拉控件后设置为true。这将有助于处理Http protocole无状态的事实,因此我们需要自己处理控件的状态。否则,在页面回发之后,它们的状态被清除,ASP .NET引擎无法找到触发回发事件的控件,并且它将使每个动态控件的状态丢失。< / p>

正如您在创建下拉列表时所看到的,我还在其上附加了一个click事件处理程序,并使它们成为autopostback = true。这样他们就会在价值变化时立即触发回发。这是为了演示如何解决问题,您可以根据需要自定义它。

现在,dropdownlist selectindexchanged事件处理程序

void drp_splzn_SelectedIndexChanged(object sender, EventArgs e)
    {
        DropDownList chosenDropDown = (DropDownList)sender;
        Int32 pickedValue = Int32.Parse(chosenDropDown.SelectedValue);
        Table table = new Table();

        for (int i = 0; i < pickedValue; i++)
        {

            TableRow row = new TableRow();
            TableCell cell = new TableCell();
            cell.Attributes.Add("runat", "server");

            TextBox txt_splzn = new TextBox();

            txt_splzn.ID = "txtB" +  i.ToString();
            txt_splzn.Text = "Text Number " + i.ToString();

            cell.Controls.Add(txt_splzn);

            row.Cells.Add(cell);
            table.Rows.Add(row);

        }

        Page.Form.Controls.Add(table);

        Response.Write("Change occured...");


    }

正如您在代码中看到的那样,它在下拉列表中创建了与所选值一样多的文本框,并在这些文本框的Text属性中添加了一个简单的文本。我还给了他们唯一的ID。

我们再次将表格添加到Page的表单控件中。

现在我们需要正确处理PostBack现象。在Asp.Net中,由于HTTP是无状态的,引擎允许我们处理两种页面加载。第一次发生的页面加载:在这种情况下,Page.IsPostback为false(第一次加载)和其他时间发生的页面加载(在这种情况下,Page.IsPostBack为true)

所以这里当Page是PostBack并且hasDropDowns为true时,这意味着我已经完成了创建动态下拉列表并为它们分配selectindex更改处理程序的过程,因此我需要一致的状态我需要完全重新创建它们我是第一次做的。然后,只有这样,ASP.NET才能正确地将它们绑定到selectindexchange事件处理程序并正确处理事件。

这是Page.Load事件处理程序的代码以及hasDropDowns静态布尔变量的声明

 static bool hasDropDowns = false;
    protected void Page_Load(object sender, EventArgs e)
    {

        if (Page.IsPostBack)
        {
            if (!hasDropDowns)
            {
                return;
            }

            Table table = new Table();

            for (int i = 1; i <= 5; i++)
            {
                TableRow row = new TableRow();
                TableCell cell = new TableCell();
                cell.Attributes.Add("runat", "server");

                DropDownList drp_splzn = new DropDownList();

                drp_splzn.ID = i.ToString();
                drp_splzn.Items.Add("-SELECT SPECIALIZATION-");
                drp_splzn.Items.Add(new ListItem("1", "1"));
                drp_splzn.Items.Add(new ListItem("2", "2"));
                drp_splzn.Items.Add(new ListItem("3", "3"));
                drp_splzn.Items.Add(new ListItem("4", "4"));
                drp_splzn.Items.Add(new ListItem("5", "5"));

                drp_splzn.SelectedIndexChanged += drp_splzn_SelectedIndexChanged;
                drp_splzn.AutoPostBack = true;
                drp_splzn.EnableViewState = true;


                cell.Controls.Add(drp_splzn);

                row.Cells.Add(cell);
                table.Rows.Add(row);
            }

            this.Controls.Add(table);

            Page.Form.Controls.Add(table);

        }
        else
        {

        }



    }

以下是一些显示工作正常的图像。

The dropdownlist

Selecting a value

The result

答案 2 :(得分:0)

以下是您上一期的解决方案。这正是我与您分享的想法的实现。

以下是一些插图图片和下面的代码

Illustration_1

Illustration_2

首先在protected void Button1_Click方法中,我在每个下拉列表下添加一个空表。因为它是空的,所以最初不会显示。

以下是代码:

protected void Button1_Click(object sender, EventArgs e)
    {

        Table table = new Table();

        for (int i = 1; i <= 5; i++)
        {
            TableRow row = new TableRow();
            TableCell cell = new TableCell();
            cell.Attributes.Add("runat", "server");

            DropDownList drp_splzn = new DropDownList();

            drp_splzn.ID = i.ToString();
            drp_splzn.Items.Add("-SELECT SPECIALIZATION-");
            drp_splzn.Items.Add(new ListItem("1", "1"));
            drp_splzn.Items.Add(new ListItem("2", "2"));
            drp_splzn.Items.Add(new ListItem("3", "3"));
            drp_splzn.Items.Add(new ListItem("4", "4"));
            drp_splzn.Items.Add(new ListItem("5", "5"));

            drp_splzn.SelectedIndexChanged += drp_splzn_SelectedIndexChanged;
            drp_splzn.AutoPostBack = true;
            drp_splzn.EnableViewState = true;


            cell.Controls.Add(drp_splzn);

            row.Cells.Add(cell);
            table.Rows.Add(row);

            TableRow rowT = new TableRow();
            TableCell cellT = new TableCell();
            cellT.Attributes.Add("runat", "server");

            Table table2 = new Table();

            table2.ID = "table" + i.ToString();

            cellT.Controls.Add(table2);

            rowT.Cells.Add(cellT);
            table.Rows.Add(rowT);



        }

         this.Controls.Add(table);

        Page.Form.Controls.Add(table);
        hasDropDowns = true;
    }

当然,您必须像我在此处所做的那样复制Page_Load中的这些更改:

 protected void Page_Load(object sender, EventArgs e)
    {

        if (Page.IsPostBack)
        {
            if (!hasDropDowns)
            {
                return;
            }

            Table table = new Table();

            for (int i = 1; i <= 5; i++)
            {
                TableRow row = new TableRow();
                TableCell cell = new TableCell();
                cell.Attributes.Add("runat", "server");

                DropDownList drp_splzn = new DropDownList();

                drp_splzn.ID = i.ToString();
                drp_splzn.Items.Add("-SELECT SPECIALIZATION-");
                drp_splzn.Items.Add(new ListItem("1", "1"));
                drp_splzn.Items.Add(new ListItem("2", "2"));
                drp_splzn.Items.Add(new ListItem("3", "3"));
                drp_splzn.Items.Add(new ListItem("4", "4"));
                drp_splzn.Items.Add(new ListItem("5", "5"));

                drp_splzn.SelectedIndexChanged += drp_splzn_SelectedIndexChanged;
                drp_splzn.AutoPostBack = true;
                drp_splzn.EnableViewState = true;


                cell.Controls.Add(drp_splzn);

                row.Cells.Add(cell);
                table.Rows.Add(row);

                TableRow rowT = new TableRow();
                TableCell cellT = new TableCell();
                cellT.Attributes.Add("runat", "server");

                Table table2 = new Table();

                table2.ID = "table" + i.ToString();

                cellT.Controls.Add(table2);

                rowT.Cells.Add(cellT);
                table.Rows.Add(rowT);
            }

            this.Controls.Add(table);

            Page.Form.Controls.Add(table);

        }
        else
        {

        }



    }

最后在void drp_splzn_SelectedIndexChanged中,而不是使用Table table = new Table();实现新表,我们用检索前一个表控件的代码替换这行代码。我们在此方法的第一行中检索到的chosenDropDown将帮助我们:它的ID是相应的数字。因此,要查找的ID是“table”+ chosenDropDown.ID 同样在此方法的最后,我们不必添加此表,因为它已经是页面的一部分。所以我评论了Page.Form.Controls.Add(table);代码行

以下是相应的代码:

void drp_splzn_SelectedIndexChanged(object sender, EventArgs e)
{

        DropDownList chosenDropDown = (DropDownList)sender;

        Int32 pickedValue = Int32.Parse(chosenDropDown.SelectedValue);

        Table table = // new Table();
         (Table)Page.Form.FindControl("table" + chosenDropDown.ID);

        for (int i = 0; i < pickedValue; i++)
        {

            TableRow row = new TableRow();
            TableCell cell = new TableCell();
            cell.Attributes.Add("runat", "server");

            TextBox txt_splzn = new TextBox();

            txt_splzn.ID = "txtB" + i.ToString();
            txt_splzn.Text = "Text Number " + i.ToString();

            cell.Controls.Add(txt_splzn);

            row.Cells.Add(cell);
            table.Rows.Add(row);

        }

        //Page.Form.Controls.Add(table);

        Response.Write("Change occured...");


    }