我一直在寻找,我迷失了如何做我想做的事情。
我正在尝试创建一个表单,其中第一列是名称列表,下一列是所有下拉列表。这个想法是,对于每个名称,用户将拍摄一个值。每个名称可能需要两个,或三个或更多值。我想创建一个动态表单,用户可以在行中单击添加,然后会出现另一个下拉列表。
实施例。 “名字”|添加按钮|下拉
然后当我点击添加...
“姓名”|添加按钮| DropDown |下拉
并继续前进。
我可以创建表单,并让它创建下拉列表。问题是我在转发器的ItemCommand上添加控件,因此必须每次都重新创建它们。因此,当我不得不重新创建它们时,我找不到一种方法来保持每个下拉列表中选择的值。
通常只需要两个下拉菜单,但有一些情况下需要三个下拉菜单,而且可能会出现更多。我想尽可能保持这种动态。
我知道如果我在页面Init中添加了下拉列表,它们将在回发中保留,但至少在我的设计中,用户必须单击“添加”以获得另一个下拉列表。
有没有办法从这些下拉列表中捕获数据,然后每次重新加载它们?或者更好的方法来实现这个功能?
感谢您的帮助。
以下是我正在使用的一些asp和代码。这是按照我的意愿运行,但我不知道如何将数据保留在回发上,因为我添加的所有下拉列表都丢失了。
ASP:
<table>
<asp:Repeater ID="repChemicals" runat="server" OnItemCommand="repChemicals_OnItemCommand">
<ItemTemplate>
<tr>
<td>
<asp:HiddenField ID="hfNumber" runat="server" />
<%# Eval("ChemicalName") %>
</td>
<td>
<asp:Button runat="server" ID="btnAdd" Text="Add" CommandArgument="ADD" />
</td>
<td>
<div id="divContainer" runat="server">
<asp:DropDownList runat="server" Width="60px" ID="ddlTest"></asp:DropDownList>
</div>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
C#:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<Chem> Chemicals = new List<Chem>();
Random rnd = new Random();
for (int z = 0; z <= 10; z++)
{
List<string> t = new List<string>();
Chem a = new Chem()
{
ChemicalName = "Chemical" + z.ToString()
};
Chemicals.Add(a);
}
repChemicals.DataSource = Chemicals;
repChemicals.DataBind();
}
}
public void repChemicals_OnItemCommand(object sender, RepeaterCommandEventArgs e)
{
int number = 0;
foreach (RepeaterItem i in repChemicals.Items)
{
HiddenField hf = (HiddenField)repChemicals.Items[i.ItemIndex].FindControl("hfNumber");
if (i.ItemIndex == e.Item.ItemIndex)
{
if (!string.IsNullOrWhiteSpace(hf.Value))
{
number = Convert.ToInt16(hf.Value) + 1;
}
else
{
number = 1;
}
hf.Value = number.ToString();
}
else
{
if (!string.IsNullOrWhiteSpace(hf.Value))
{
number = Convert.ToInt16(hf.Value);
}
else
{
number = 0;
}
}
for (int x = 0; x < number; x++)
{
DropDownList ddl = new DropDownList();
ddl.Style.Add("width", "60px");
ddl.ID = "ddl" + i.ToString() + x.ToString();
ddl.Style.Add("Margin-right", "3px");
ddl.Attributes.Add("runat", "server");
ddl.DataSource = DataSource();
ddl.DataBind();
Control c = repChemicals.Items[i.ItemIndex].FindControl("divContainer");
c.Controls.Add(ddl);
}
}
一些循环用于创建测试数据。基本上我在隐藏字段中的每一行上存储了许多动态控件。然后在item命令中,我循环遍历所有行并重新创建所有先前存在的ddl,并将一个添加到teh命令来自的行。
答案 0 :(得分:1)
这并不能完全回答你的问题,但是它以一种不那么复杂的方式实现了你的最终目标,并且利用了内置的ASP.NET控件,因此可以为你保留回发之间的状态。
它使用jQuery,jQuery UI和DropDownChecklist插件。
ASPX
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.21/jquery-ui.min.js"></script>
<script type="text/javascript" src="js/ui.dropdownchecklist.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.21/themes/base/jquery-ui.css"/>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<asp:Repeater ID="repChemicals" runat="server">
<ItemTemplate>
<tr>
<td>
<%# Container.DataItem %>
</td>
<td>
<div id="divContainer" runat="server">
<asp:ListBox ID="lstAttributes" SelectionMode="Multiple" runat="server"></asp:ListBox>
</div>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
<asp:Button ID="btnPostback" Text="Postback" runat="server"/>
</div>
</form>
</body>
</html>
C#
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace PersonAttributes
{
public partial class People : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
repChemicals.ItemCreated += RepChemicalsOnItemCreated;
var chemicals = new[] {"Hydrogen", "Helium", "Lithium", "Beryllium", "Boron"};
if(!IsPostBack)
{
repChemicals.DataSource = chemicals;
repChemicals.DataBind();
}
var dropDownChecklist = "$(document).ready(function () { $('select').dropdownchecklist(); });";
ScriptManager.RegisterStartupScript(this,GetType(),"initDropDownChecklist",dropDownChecklist,true);
}
private void RepChemicalsOnItemCreated(object sender, RepeaterItemEventArgs repeaterItemEventArgs)
{
var lst = repeaterItemEventArgs.Item.FindControl("lstAttributes") as ListBox;
if (lst == null)
return;
lst.DataSource = new[] {"Option 1", "Option 2", "Option 3"};
}
}
}
在CodeRun看到它的实际效果。