【问题标题】:dynamically generated checkboxes' checked property appears as false, regardless of their actual state动态生成的复选框的选中属性显示为 false,无论其实际状态如何
【发布时间】:2012-07-10 11:17:51
【问题描述】:

我有一个使用页面上的控件(“添加”按钮和数量文本框)填充“产品”的 asp:Table。 在我后面的代码中,每当要添加表项时,我首先创建一个 Product 实例,设置其属性,然后将其添加到产品列表中。然后我对表格执行以下操作: - 清除其行集合 - 添加标题行 - 将表格绑定到产品列表 - 缓存产品列表,以备后用

表格中的每一行都以一个包含复选框的单元格开头。表格下方是一个“全部清除”链接按钮。单击清除所有链接按钮时, 我将它引导到一个方法来循环遍历所有 CheckBox,确定它们是否被选中,如果选中 == true,则删除产品列表中的相应条目。 因此,理论上,当我将 Products 列表重新绑定到 Table 时,应该删除选中其 CheckBoxes 的行。

如果表中有单个行,则此方法有效:调试时,CheckBox 的选中属性显示为“true”,并且该行被删除。但是,如果有不止一行,则选中的属性为 所有 CheckBoxes 都显示为“false”,并且没有任何内容被删除。

编辑 - 它实际上似乎删除了表格的最后一行,尽管其余的 CheckBoxes 被视为未选中。

这是页面上的表格:

<asp:Table ID="tblProducts" runat="server">
<asp:TableHeaderRow ID="tblProductsHead" runat="server" BorderStyle="Solid">
    <asp:TableHeaderCell ID="colCheckBox" runat="server" Text="">
        <asp:CheckBox ID="chkSelectAll" runat="server" Text="" />
    </asp:TableHeaderCell>
    <asp:TableHeaderCell ID="colProduct" runat="server" Text="Product"><asp:TableHeaderCell>
    <asp:TableHeaderCell ID="colValue" runat="server" Text="Value"></asp:TableHeaderCell>
    <asp:TableHeaderCell ID="colQuantity" runat="server" Text="Quantity"></asp:TableHeaderCell>
    <asp:TableHeaderCell ID="colTotalValue" runat="server" Text="Total Value"></asp:TableHeaderCell>
</asp:TableHeaderRow>
</asp:Table>
<asp:LinkButton ID="lbtnClearAll" runat="server" Text="Clear All" 
    onclick="lbtnClearAll_Click"></asp:LinkButton>

...这里是代码隐藏的相关部分:

 private void ClearSelectedTableRows()
    {
        if (Cache["TableRows"] != null)
        {
            tableRows = Cache["TableRows"] as List<TableRow>;
            Cache.Remove("TableRows");

            TableRow row = new TableRow();
            CheckBox rowBox = new CheckBox();

            for (int i = 0; i < tableRows.Count; i++)
            {
                row = tblProducts.Rows[i+1]; // skip header row
                rowBox = row.Cells[0].Controls[0] as CheckBox;

                if (rowBox.Checked)
                    tableRows.RemoveAt(i);

            }

            TableRow headRow = tblProductsHead;
            tblProducts.Rows.Clear();
            tblProducts.Rows.Add(headRow);
            Cache.Insert("TableRows", tableRows, null, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration);
            PopulateTable();                
        }
    }


private void PopulateTable()
    {
        if (Cache["TableRows"] != null)
        {
            List<TableRow> rows = Cache["TableRows"] as List<TableRow>;
            foreach (TableRow row in rows)
                tblProducts.Rows.Add(row);
        }
    }

【问题讨论】:

  • 好吧,在我的脑海中,我没有看到任何特别的东西。但是你如何填充你的Cache["TableRows"]?也许这是您创建代码的疏忽。此外,在您的 ClearSelectedTableRows 方法中,TableRow row = new TableRow();CheckBox rowBox = new CheckBox() 是不必要的;只需在 for 循环中声明它们。编辑:另外,你的 for 循环看起来很奇怪。你应该从int i = 1 开始;您“跳过标题行”,但随后向下三行删除当前行(可能是标题行!)
  • 根据您的编辑,尝试将行 tableRows.RemoveAt(i); 更改为 tableRows.RemoveAt(i + 1);
  • 谢谢 Chis,我会看看创建它们的代码。关于循环:带有 i+1 的部分正在获取页面上表中复选框的值。在“tableRows.RemoveAt(i)”部分,它指的是表格将绑定到的列表,它没有标题行。

标签: c# asp.net web-controls


【解决方案1】:

我也认为你的循环看起来很奇怪,并同意你也应该从 i=1 开始。 一个快速的答案是在删除一行后立即使用--i

【讨论】:

  • 感谢您的回答。这可能看起来很奇怪,但它的工作原理,这对我来说很重要:) 无论我在一个地方添加到“i”还是在另一个地方减去它,它都会有相同的最终结果
【解决方案2】:

有人留下了答案,说控件需要 ID 才能正确评估其属性,但随后将其删除。无论如何,这被证明是问题的根源。在创建代码中给复选框 ID 后,它就开始工作了。

但是,使用 RemoveAt() 方法会导致更多问题;我使用“tableRows”列表的计数作为循环的长度,同时可能会更改循环内该列表的长度。

现在已经修复了,下面是更新的方法:

    private void ClearSelectedTableRows()
    {
        if (Cache["TableRows"] != null)
        {
            tableRows = Cache["TableRows"] as List<TableRow>;
            Cache.Remove("TableRows");

            TableRow row = new TableRow();
            CheckBox rowBox = new CheckBox();
            List<TableRow> rowsToRemove = new List<TableRow>();
            for (int i = 0; i < tableRows.Count; i++)
            {
                row = tblProducts.Rows[i+1]; // skip header row
                rowBox = row.Cells[0].Controls[0] as CheckBox;

                if (rowBox.Checked)
                    rowsToRemove.Add(tableRows[i]);                    
            }

            foreach (TableRow removeRow in rowsToRemove)
            {
                if (tableRows.Contains(removeRow))
                    tableRows.Remove(removeRow);
            }

            TableRow headRow = tblProductsHead;
            tblProducts.Rows.Clear();
            tblProducts.Rows.Add(headRow);
            Cache.Insert("TableRows", tableRows, null, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration);
            PopulateTable();                
        }            
    }

感谢提供帮助的人,感谢幻影回答者!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    相关资源
    最近更新 更多