如何从asp.net中动态生成的复选框列表中获取复选框值

时间:2012-04-16 18:31:16

标签: c# asp.net checkbox

在网络表单中,我动态创建一系列添加到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控件这样的其他控件,而不是将这些元素写入占位符吗?

有人可以就如何检索复选框值向我提供一些指导吗?

4 个答案:

答案 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从行动到行动。