如何以编程方式创建和使用ASP.NET中的复选框列表?

时间:2009-07-24 22:16:43

标签: asp.net forms checkbox

我有一个包含东西表的页面,我需要允许用户选择要处理的行。我已经想出如何在表格中添加一列复选框,但我似乎无法弄清楚如何在提交表单时检查它们是否被检查。如果它们是静态元素,我只能检查do this.theCheckBox但是它们是以编程方式生成的。

此外,我对我将数据附加到他们的方式(通过将其填充到ID属性中)感到不满意。

我不确定它是否相关,但我正在看一下catch-22,因为我需要知道在我之前检查了哪些上次创建的复选框可以重新运行创建它们的代码。


编辑: 我找到了一个几乎解决方案。通过设置AutoPostBack属性和CheckedChanged事件:

checkbox.AutoPostBack = false;
checkbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged);

对于任何已更改的复选框,我都可以在帖子后面调用代码。然而,这有两个问题:

  • 在我需要使用此信息之后(或期间,我不确定)Page_Load处理回叫
  • 对于在加载页面时仍然检查的复选框,不会调用回调函数。

编辑2:

我最终做的是使用已知前缀标记我的所有ID,并将其填入Form_Load的顶部:

foreach (string v in this.Request.Form.AllKeys)
{
    if (v.StartsWith(Prefix))
    {
        var data = v.Substring(Prefix.Length);
    }
}

其他一切似乎都迟到了。

7 个答案:

答案 0 :(得分:2)

我将假设您正在使用DataList,但这应该与可以模板化的Control和Control一起使用。我也假设您正在使用DataBinding。

代码前线:

<asp:DataList ID="List" OnItemDataBound="List_ItemDataBound" runat="server">
    <ItemTemplate>
        <asp:CheckBox ID="DeleteMe" runat="server"/>
        <a href="<%# DataBinder.Eval(Container, "DataItem.Url")%>" target="_blank">
            <%# DataBinder.Eval(Container, "DataItem.Title")%></a>
    </ItemTemplate>
</asp:DataList>
<asp:Button ID="DeleteListItem" runat="server" OnClick="DeleteListItem_Click" ></asp:Button>

代码背后:

public partial class Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadList();
    }

    protected void DeleteListItem_Click(object sender, EventArgs e)
    {
        foreach (DataListItem li in List.Items)
        {
            CheckBox delMe = (CheckBox)li.FindControl("DeleteMe");

            if (delMe != null && delMe.Checked)
                    //Do Something
            }
        }

        LoadList();
    }

    protected void LoadList()
    {
        DataTable dt = //Something...
        List.DataSource = dt;
        List.DataBind();
    }

    protected void List_ItemDataBound(object sender, DataListItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
        {
            string id = DataBinder.Eval(e.Item.DataItem, "ID").ToString();
            CheckBox delMe = (CheckBox)e.Item.FindControl("DeleteMe");

            if (delMe != null)
                delMe.Attributes.Add("value", id);                
        }
    }
}

答案 1 :(得分:1)

首先,确保每个Checkbox都有一个ID,并且标签中有'runat =“server”'。

然后使用FindControl()函数找到它。

例如,如果您循环遍历GridView中的所有行..

foreach(GridViewRow r in Gridview1.Rows)
{

    object cb = r.FindControl("MyCheckBoxId");
    if(r != null)
    {
      CheckBox chk = (CheckBox)cb;
      bool IsChecked = chk.Checked;
    }

}

答案 2 :(得分:1)

在InitComplete事件和PreLoad事件之间恢复回发数据。如果您的复选框直到稍后才创建,则复选框将对其事件进行“追赶”,并且数据将在创建后立即加载到控件中。
如果这对你迟到,那么你将不得不做你已经在做的事情。也就是说,在将数据提供给控件之前,您必须访问它们 如果您可以保存您创建的每个UniqueId的{​​{1}},则可以直接访问帖子数据,而无需为其提供特殊前缀。您可以通过创建一个字符串列表来执行此操作,您可以在生成它们时将其保存,然后将它们保存在视图状态中。当然,这需要启用视图状态并在视图状态中占用更多空间。

CheckBox

答案 3 :(得分:0)

你的帖子有点模糊。这将有助于了解如何向表中添加控件。它是一个ASP:表格还是常规HTML表格(可能是因为你已经成功地向它添加了项目,所以有一个runat =“server”属性)?

如果您打算让用户进行一系列选择,然后点击“提交”按钮,您将根据检查的行处理每一行,然后您不应该处理CheckChanged事件。否则,正如您所注意到的,每次都会导致回发,并且不会处理任何其他复选框。因此,当您创建CheckBox时,请不要设置eventhandler,因此它不会导致回发。

在提交按钮的事件处理程序中,您将循环遍历每个表格行,单元格,然后确定单元格的子控件是否包含复选框。

我建议不要使用表格。根据您的描述,GridView或DataList可能是更好的选择。


编辑:这是一个简单的示例。您应该能够在新项目中进行测试。

<强>标记

    <form id="form1" runat="server">
    <div>
    <table id="tbl" runat="server"></table>
    <asp:Button ID="btnSubmit" runat="server" Text="Submit"
      onclick="btnSubmit_Click" />
    </div>
    </form>

<强>代码隐藏

protected void Page_Load(object sender, EventArgs e)
{
    for (int i = 0; i < 10; i++)
    {
        var row = new HtmlTableRow();
        var cell = new HtmlTableCell();
        cell.InnerText = "Row: " + i.ToString();
        row.Cells.Add(cell);
        cell = new HtmlTableCell();
        CheckBox chk = new CheckBox() { ID = "chk" + i.ToString() };
        cell.Controls.Add(chk);
        row.Cells.Add(cell);
        tbl.Rows.Add(row);
    }
}

protected void btnSubmit_Click(object sender, EventArgs e)
{
    foreach (HtmlTableRow row in tbl.Rows)
    {
        foreach (HtmlTableCell cell in row.Cells)
        {
            foreach (Control c in cell.Controls)
            {
                if (c is CheckBox)
                {
                    // do your processing here
                    CheckBox chk = c as CheckBox;
                    if (chk.Checked)
                    {
                        Response.Write(chk.ID + " was checked <br />");
                    }
                }
            }
        }
    }
}

答案 4 :(得分:0)

使用CheckBoxList控件怎么样?我现在没有打开Visual Studio,但据我记得它是一个DataBound控件,提供DataSourceDataBind(),您可以在运行时提供列表。当页面执行回发时,您可以通过调用类似myCheckBoxList.Items的内容来遍历列表,并通过调用ListItem.Selected方法检查当前项是否已被选中。这应该有用。

答案 5 :(得分:0)

在页面的CreateChildControls方法的重写中添加它们。一定要给他们一个ID!这样,它们就会在正确的时间添加到控制树中。

恕我直言最好的方法是使用DataBound Templated Control,即像ListView(在.NET 3.5中)。然后在回跳后遍历页面加载数据绑定控件中的所有项目并使用item.FindControl来获取实际的复选框。

答案 6 :(得分:0)

我最终做的是使用已知前缀标记我的所有ID,并将其填入Form_Load的顶部:

foreach (string v in this.Request.Form.AllKeys)
{
    if (v.StartsWith(Prefix))
    {
        var data = v.Substring(Prefix.Length);
    }
}

其他一切似乎都迟到了。