全选/取消全选复选框

4

我有一个复选框列表,它从SQL表中获取其项目,并根据从下拉菜单中选择的内容进行更改。我试图在该列表中添加另一个复选框,该复选框充当全选/取消全选框。我在这个站点上看到了一些示例,但似乎没有什么正常工作。

预期功能:

当选中此框时,所有其他框都被选中。

当取消选中此框时,所有其他框都被取消选中。

当选中此框时,如果另一个框然后被取消选中,则取消全选框也会被取消选中。

C#:

List<ListItem> toBeRemoved = new List<ListItem>();

//removes items when new item from dropdown is selected
for (int i = 1; i < CheckOpenTimesheets.Items.Count; i++)
{
    toBeRemoved.Add(CheckOpenTimesheets.Items[i]);
}
for (int i = 0; i < toBeRemoved.Count; i++)
{
    CheckOpenTimesheets.Items.Remove(toBeRemoved[i]);
}
lblOpenTimesheets.Text = "";
String sql = "sql statement here";
command.CommandText = sql;
command.Parameters.Add(new SqlParameter("userid", ddlActingAs.SelectedValue.ToString()));

SqlDataReader reader = command.ExecuteReader();

//Adds items to the checkboxlist
while (reader.Read())
{
    ListItem item = new ListItem();
    item.Text += reader.GetDateTime(0).ToString("MM/dd/yyyy") + " is open";
    item.Value = reader["StartDate"].ToString();

    CheckOpenTimesheets.Items.Add(item);
}
CheckOpenTimesheets.UpdateAfterCallBack = true;
reader.Close();

我尝试进行选择/取消选择的方法:

protected void select_DeselectAll(object sender, System.EventArgs e)
{
    if (CheckOpenTimesheets.Items[0].Selected == true)
    {
        foreach (ListItem item in CheckOpenTimesheets.Items)
        {
            item.Selected = true;
        }
    }
    else
    {
        foreach (ListItem item in CheckOpenTimesheets.Items)
        {
            item.Selected = false;
        }
    }
}

ASP:

<anthem:CheckBoxList ID="CheckOpenTimesheets" OnSelectedIndexChanged="select_DeselectAll" runat="server" AutoPostBack="true" >
    <asp:ListItem Text="Select/Deselect All"  />
</anthem:CheckBoxList>

编辑:问题似乎是当选择“全选”以外的复选框时,OnSelectedIndexChanged事件会触发。

编辑2:将“全选”复选框与复选框列表分开。但是,当试图实现这样一个功能,即如果在选中了“全选”复选框的情况下取消选择某个复选框,则“全选”复选框将被取消选择,但所有其他复选框不会“取消选择”。然而,这并没有发生,因为“全选”复选框的事件已经触发了。

protected void chkAll_CheckedChanged(object sender, EventArgs e)
{
    foreach (ListItem item in CheckOpenTimesheets.Items)
    {
        item.Selected = chkAll.Checked;
    }
}

protected void checkbox_Selected(object sender, EventArgs e)
{
    chkAll.CheckedChanged -= chkAll_CheckedChanged;

        foreach (ListItem item in CheckOpenTimesheets.Items)
        {
            if ((item.Selected = false) && (chkAll.Checked = true))
            {
                chkAll.Checked = false;
            }
        }       
}

哪里出了问题?是添加全选/取消全选项吗?还是实际执行其他项目的选择和取消选择? - j.f.
更新了我的代码,尝试实现选择/取消选择功能。我已经在 ASP 代码中添加了选择/取消选择项目。 - pfinferno
可能是事件的顺序问题。您可能会勾选/取消所有内容,然后重新构建列表。无论如何,您可能希望考虑使用JavaScript/Jquery在客户端执行此操作。这将更加用户友好且更快。 - Steve Wellens
有没有办法使onselectedIndexChanged事件仅适用于第一个复选框,即全选?这似乎是问题所在。 - pfinferno
1个回答

3

听起来你已经理解了你的问题。问题出现在你点击除第一个复选框以外的任何其他复选框时。如果第一个没有被选中,而你又勾选了另一个复选框,那么你的逻辑会告诉所有其他复选框都不要被选中,包括你刚刚勾选的那个。

一个选项是将“全选/取消全选”复选框从CheckBoxList中移除。让它成为独立的复选框。

<asp:CheckBox ID="chkAll" runat="server" Text="Select/Deselect All" OnCheckedChanged="chkAll_CheckedChanged" AutoPostBack="true" />
<anthem:CheckBoxList ID="checkOpenTimesheets" OnSelectedIndexChanged="checkOpenTimesheets_SelectedIndexChanged" runat="server" AutoPostBack="true" >
</anthem:CheckBoxList>

您的“选择全部”事件处理程序只需将它们全部更改为相同即可。
protected void chkAll_CheckedChanged(object sender, EventArgs e)
{
    foreach(ListItem item in CheckOpenTimesheets.Items)
    {
        item.Selected = chkAll.Checked;
    }
}

然后,还要构建功能,在CheckBoxList中的任何内容发生变化时,以编程方式选择或取消选择“全选/取消全选”复选框,如果其他所有复选框中有任何一个变成与其他复选框不同的状态。正如这个答案中所解释的那样,关键在于关闭“全选”复选框的CheckedChanged事件,否则该事件将按您所见的那样触发。
protected void checkOpenTimesheets_SelectedIndexChanged(object sender, EventArgs e)
{
    chkAll.CheckedChanged -= chkAll_CheckedChanged;

    CheckBoxList checkOpenTimesheets = (CheckBoxList)sender;
    if (allItemsCheckedInCheckBoxList(checkOpenTimesheets))
    {
        chkAll.Checked = true;
    }
    else if (allItemsUnCheckedInCheckBoxList(checkOpenTimesheets))
    {
        chkAll.Checked = false;
    }

    chkAll.CheckedChanged += chkAll_CheckedChanged;
}

private bool allItemsCheckedInCheckBoxList(CheckBoxList checkBoxList)
{
    bool allItemsChecked = true;

    foreach (ListItem item in checkBoxList.Items)
    {
        allItemsChecked = item.Selected;

        if (!allItemsChecked)
            break;
    }

    return allItemsChecked;
}

private bool allItemsUnCheckedInCheckBoxList(CheckBoxList checkBoxList)
{
    bool allItemsUnChecked = false;

    foreach (ListItem item in checkBoxList.Items)
    {
        allItemsUnChecked = item.Selected;

        if (allItemsUnChecked)
            break;
    }

    return allItemsUnChecked;
}

好的,我按照你说的做了,并将其制作成了一个单独的复选框。但是在选择/取消其他复选框时,无法选择/取消“全选”复选框。我编写了代码来比较所选项目和“全选”复选框,然后选中/取消“全选”复选框。但是当这种情况发生时,它会调用chkAll_CheckedChanged方法并选择/取消所有复选框。 - pfinferno
@pfinferno - 请查看这个答案,我认为那就是你需要的。 - j.f.
尝试实现该链接上第二个答案https://dev59.com/qmsz5IYBdhLWcg3wJUfJ#8089153。但似乎无法正确执行,我已更新我的答案,包括两种方法(用于全选复选框和复选框列表)。 - pfinferno
在 aspx 代码的 checkedchanged 事件中调用了哪个方法?是 allItemsChecked 还是 allItemsUnchecked? - pfinferno
1
这两个方法只是辅助方法,它们并不是事件本身。chkAll_CheckedChangedcheckOpenTimesheets_SelectedIndexChanged 是被调用的两个事件。 - j.f.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接