在网络表单中,我动态创建一系列添加到asp:placeholder
的chekbox//Generates the List of Entities that may be shared
protected void GenerateEntityList(string agencyId, string agencyName)
{
var selectedAgency = UserFactory.GetAgencyAndSharedDataById(Convert.ToInt64(agencyId));
entityContainer.Controls.Clear();
//builds the entity list based upon entities in DB
var currentEntities = UserFactory.GetEntityList();
//add checkboxes
entityContainer.Controls.Add(new LiteralControl("<input type='checkbox' id='selectAllCB' value='All'>Select All<br/><br/>"));
foreach (var item in currentEntities)
{
CheckBox entityCheckBox = new CheckBox();
int currentItem = item.EntityTypeId.GetValueOrDefault(0);
entityCheckBox.Text = item.EntityName.ToString();
entityCheckBox.CssClass = "am_Checkbox";
entityContainer.Controls.Add(entityCheckBox);
entityContainer.Controls.Add(new LiteralControl("<br/><br/>"));
//mark checkboxes as checked if currently stored in the database
if (selectedAgency.FirstOrDefault().SecurityDataShares != null && selectedAgency.FirstOrDefault().SecurityDataShares.Count > 0)
{
foreach (var ce in selectedAgency.FirstOrDefault().SecurityDataShares)
{
if (ce.EntityId == item.EntityId)
{
entityCheckBox.Checked = true;
}
}
}
}
创建后,用户可以创建或删除选择。单击更新时,我想返回/收集复选框中的值,以便我可以将它们插回到数据库中。
//get the text value of every checkbox
protected void updateEnties()
{
string receivingAgency = ReceivingAgencyID;
long contributingAgency = QueryID;
List<string> cbValues = new List<string>();
foreach (CheckBox currentItem in entityContainer.Controls)
{
cbValues.Add(currentItem.Text);
}
}
然而,当我尝试迭代集合时,我没有得到任何回复,这导致我相信我正在错误地调用控件或者由于回发而被销毁。 我应该使用像Listbox控件这样的其他控件,而不是将这些元素写入占位符吗?
有人可以就如何检索复选框值向我提供一些指导吗?
答案 0 :(得分:4)
有两种思想流派;一,您需要重新创建为初始视图创建的控件层次结构,以便页面可以将视图状态和表单值还原到控制树中,或者两个,您可以使用低技术解决方案并简单地获取表单集合中的值。
我个人而言,就像选项二一样,处理相对容易,因为看起来你已经用LiteralControl
手动创建了HTML。只需提供一个name
属性,该属性在您手动创建的输入标记之间共享(为简洁起见,此处显示的示例可能不是您要做的):
entityContainer.Controls.Add(new LiteralControl("<input type='checkbox' name='mySharedName' />");
然后,要获得值,就像这样简单:
var selectedValues = Request.Form["mySharedName"];
// This is now a comma separated list of values that was checked
然后你不必担心控制树状态。
答案 1 :(得分:2)
听起来你只需使用CheckBoxList
就可以让生活变得更轻松,并将结果集绑定到它。这实际上会使对任何动态内容的需求无效。
<asp:CheckBoxList ID="CheckList1" runat="server" DataTextField="TextColumn" DataValueField="ValueColumn" ...>
如果这不是一个选项,那么您需要在每次回发后重新创建控件。有几种方法可以做到这一点。
简单方法
查看DynamicControlsPlaceHolder控件。这是一个有用的小控件,负责在幕后持久保存动态内容。我会建议这个选项,因为它会消除动态创建内容的所有痛苦。
手动方式
在OnInit
期间重新创建控件。只需确保为控件分配相同的ID,以便ViewState可以重新填充选择:
protected override void OnInit(EventArgs e)
{
var chk = new CheckBox { ID = "chkBox1" };
PlaceHolder1.Controls.Add(chk);
base.OnInit(e);
}
在回发后重新创建控件后,您应该能够访问如下值:
foreach (CheckBox chk in PlaceHolder1.Controls.OfType<CheckBox>())
{
if (chk.Checked)
{
}
}
答案 2 :(得分:0)
感谢大家的建议。根据这是如何实施的,我向Tejs提供了答案,因为他让我沿着这个解决方案的思路前进。在这个项目中,我需要使用复选框和复选框列表控件,因为我正在构建列表并验证已检查的元素。 asp.net是如何生成复选框控件以及允许向控件插入属性(名称,值等)的限制所带来的挑战
因此,为了从代码生成复选框中捕获vales,我执行了以下操作:
在aspx文件中,我添加了一个隐藏的输入字段并分配了一个runat = server标记
<input id="cbEntityList" type="hidden" runat="server" value="" />
Tejs解决方案与此类似,但我不喜欢为每个复选框添加隐藏字段的想法,因为它看起来像页面中的很多元素。
然后我修改了复选框代码生成部分,以包含来自我的对象的唯一标识符作为Id。 ID在html中作为name属性呈现出来,这样我就能用javascript / jQuery检索一些东西
因此,在我要构建复选框的foreach语句中,我添加了以下行
entityCheckBox.ID = item.EntityId.ToString();
最后,我使用jQuery迭代页面以获取复选框,并返回仅检查项目的字符串数组。
这会根据选中的复选框填充隐藏的字段,例如(0,1,2,3,4)。
$('#btnUpdateEntities').click(function (event) {
var fields;
$(':checkbox:checked').each(function () {
var txt = $("input[name='cbEntityList']");
fields = ($(':checkbox:checked').map(function () {
return this.name;
}).get().join(","));
$(txt).val(fields);
});
});
然后我可以在我的代码后面访问值数组:
string voo = cbEntityList.Value;
希望这有助于任何感兴趣的人。
答案 3 :(得分:-1)
这是你应该使用OO原则组合实现的东西。在这种情况下,您应该构建自己的CheckBoxCollection(从适当的接口/类继承)。它将简化代码并使其更加划分和可扩展。
其中一个实现细节是处理你描述的情况:抛出一个点击处理程序,它添加到viewstate / session /的任何内容,你应该能够看到你的测试工具/用户检查/取消选中的任何内容。一目了然。
另一个快点:你不应该使用&lt; br /&gt;用于布局的标签,特别是如果您已经在使用CSS。你可以确保checkboxen是你需要的任何显示类型(在这种情况下是块?),然后在你已经装饰控件的CSS类中设置它。
tl; dr:我没有时间在代码中抛出一个例子,但基本的想法是你应该有一个CheckBoxCollection()(根据你的喜好)保留它的CheckBox()s'.Checked从行动到行动。