C# 如何从asp.net中动态生成的复选框列表中获取复选框值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10179589/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the checkbox value from a dynamically generated checkbox list in asp.net
提问by rlcrews
Within a web form I am dynamically creating a series of chekboxes that are added to an asp:placeholder
在 Web 表单中,我动态创建了一系列添加到 asp:placeholder 的 chekboxes
//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;
}
}
}
}
Once created the user has the ability to make or remove selections. When clicking update I would like to return/collect the values from the checkboxes so that I may insert them back into the db.
一旦创建,用户就可以进行选择或删除选择。单击更新时,我想从复选框中返回/收集值,以便我可以将它们插入回数据库中。
//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);
}
}
However when I attempt to iterate over the collection I am not getting anything back which leads me to believe either I am calling the control incorrectly or it is being destroyed due to the postback. Instead of writing these elements to a place holder should I use another controls like a Listbox control?
但是,当我尝试迭代集合时,我没有得到任何返回,这使我相信我错误地调用了控件,或者它由于回发而被破坏。我应该使用其他控件(如 Listbox 控件)而不是将这些元素写入占位符?
Can someone please provide me with some guidance on how I can retrieving the checkbox values?
有人可以就如何检索复选框值向我提供一些指导吗?
采纳答案by Tejs
There are two schools of thought; one, that you need to recreate the control hierarchy that was made for the initial view so that the page can restore the view state and form values into the control tree, or two, that you can go with a low tech solution and simply get the values from the form collection.
有两种思想流派;一,您需要重新创建为初始视图创建的控件层次结构,以便页面可以将视图状态和表单值恢复到控件树中,或两个,您可以使用低技术解决方案并简单地获取表单集合中的值。
I personally, like option two, and it's relatively easy to deal with, and since it looks like you're already manually creating the HTML with LiteralControl. Simply provide a nameattribute that is shared among your manually created input tags (example shown here for brevity, this is probably not what you will do):
我个人喜欢选项二,它相对容易处理,因为看起来您已经使用 .html 手动创建了 HTML LiteralControl。只需提供一个name在您手动创建的输入标签之间共享的属性(为简洁起见,此处显示的示例,这可能不是您要做的):
entityContainer.Controls.Add(new LiteralControl("<input type='checkbox' name='mySharedName' />");
Then, to get the values it is as simple as this:
然后,要获取值就像这样简单:
var selectedValues = Request.Form["mySharedName"];
// This is now a comma separated list of values that was checked
Then you dont have to worry about the control tree state.
那么您就不必担心控制树状态。
回答by Tonweight
This is the kind of thing for which you should put together an implementation using OO principles. In this case, you should probably build your own CheckBoxCollection (inheriting from the proper interfaces/class). It would simplify the code and make it more compartmentalized and extensible.
这是您应该使用面向对象原则组合实现的那种事情。在这种情况下,您可能应该构建自己的 CheckBoxCollection(从正确的接口/类继承)。它将简化代码并使其更加分隔和可扩展。
One of the implementation details is then handling the situation you describe: throw in a click-handler that adds to the viewstate/session/whatever and you should be able to see whatever your test harness/users have checked/unchecked at a glance.
然后,实现细节之一是处理您描述的情况:加入添加到视图状态/会话/任何内容的点击处理程序,您应该能够一目了然地看到您的测试工具/用户检查/取消检查的任何内容。
Another quick point: you shouldn't use <br /> tags for layout anymore, especially if you're already using CSS. You can make sure that checkboxen are whatever display type you need (block, in this case?), then set that in the CSS class with which you've already decorated the control.
另一个要点:您不应该再使用 <br /> 标签进行布局,特别是如果您已经在使用 CSS。您可以确保 checkboxen 是您需要的任何显示类型(在这种情况下是块?),然后在您已经装饰控件的 CSS 类中设置它。
tl;dr: I don't have time to throw up an example in code, but the basic idea is that you should have a CheckBoxCollection() which (according to your preference) preserves its CheckBox()s' .Checked states from action to action.
tl; dr:我没有时间在代码中抛出一个例子,但基本的想法是你应该有一个 CheckBoxCollection() 它(根据你的偏好)保留它的 CheckBox()s' .Checked 状态从动作行动。
回答by James Johnson
It sounds like you could make life much easier just using a CheckBoxListinstead, and binding your result set to it. That would actually nullify the need for any dynamic content.
听起来您只需使用 aCheckBoxList代替,并将您的结果集绑定到它,就可以让生活变得更轻松。这实际上将消除对任何动态内容的需求。
<asp:CheckBoxList ID="CheckList1" runat="server" DataTextField="TextColumn" DataValueField="ValueColumn" ...>
If that's not an option, then you need to recreate the controls after each postback. There are a couple ways to do this.
如果这不是一个选项,那么您需要在每次回发后重新创建控件。有几种方法可以做到这一点。
The easy way
简单的方法
Check out the DynamicControlsPlaceHoldercontrol. This is a useful little control that takes care of persisting dynamic content behind the scenes. I would suggest this option, as it takes all of the pain away from dynamically created content.
查看DynamicControlsPlaceHolder控件。这是一个有用的小控件,负责在幕后持久化动态内容。我会建议这个选项,因为它消除了动态创建的内容的所有痛苦。
The manual way
手动方式
Recreate the control(s) during OnInit. Just make sure you assign the same ID to the controls so that ViewState can repopulate the selections:
期间重新创建控件OnInit。只需确保为控件分配相同的 ID,以便 ViewState 可以重新填充选择:
protected override void OnInit(EventArgs e)
{
var chk = new CheckBox { ID = "chkBox1" };
PlaceHolder1.Controls.Add(chk);
base.OnInit(e);
}
After recreating the control after the postback, you should be able to access the values like this:
在回发后重新创建控件后,您应该能够访问如下值:
foreach (CheckBox chk in PlaceHolder1.Controls.OfType<CheckBox>())
{
if (chk.Checked)
{
}
}
回答by rlcrews
Thanks to all for your suggestions. Based upon how this was being implemented I credited Tejs with the answer as he sent me down the thought path for this solution. In this project I needed to use checkboxes vs. a checkbox list control due to how I was building the list and verifying checked elements. The challenge came in with how asp.net generates the checkbox control as well as it's limitation on allowing the insertion of attributes to the control (name, value etc)
感谢大家的建议。根据这是如何实施的,我将答案归功于 Tejs,因为他让我沿着这个解决方案的思路走下去。在这个项目中,由于我构建列表和验证选中元素的方式,我需要使用复选框与复选框列表控件。挑战来自 asp.net 如何生成复选框控件以及它对允许将属性插入控件(名称、值等)的限制
So to capture the vales from the code generated checkboxes I did the following:
因此,为了从代码生成的复选框中捕获值,我执行了以下操作:
Within the aspx file I added an hidden input field and assigned a runat=server tag
在 aspx 文件中,我添加了一个隐藏的输入字段并分配了一个 runat=server 标签
<input id="cbEntityList" type="hidden" runat="server" value="" />
Tejs solution was similar to this but I didn't like the idea of adding a hidden field for each checkbox as that seems like a lot of elements in the page.
Tejs 解决方案与此类似,但我不喜欢为每个复选框添加隐藏字段的想法,因为这看起来像是页面中的很多元素。
I then modifed the checkbox code generation piece to include as the Id a unique identifier from my object. ID gets rendered out in the html as the name attribute so this allows me to how have something I can retrieve with javascript /jQuery
然后我修改了复选框代码生成部分,将我的对象的唯一标识符作为 Id 包含在内。ID 在 html 中呈现为 name 属性,因此这使我可以使用 javascript / jQuery 检索某些内容
So within the foreach statement where I would build the checkboxes I added the following line
因此,在我将构建复选框的 foreach 语句中,我添加了以下行
entityCheckBox.ID = item.EntityId.ToString();
Finally I used jQuery to iterate the page for checkboxes and return a string array of only checked items.
最后,我使用 jQuery 迭代页面的复选框并返回一个仅包含选中项的字符串数组。
This would populate back to the hidden filed a value such as (0,1,2,3,4) based upon what checkbox was selected.
这将根据选中的复选框填充回隐藏字段的值,例如 (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);
});
});
I could then access the array of values in my code behind as:
然后我可以访问我后面的代码中的值数组:
string voo = cbEntityList.Value;
Hope this helps any interested.
希望这对任何感兴趣的人有所帮助。

