【问题标题】:Checking Checkbox in Gridview在 Gridview 中选中复选框
【发布时间】:2013-12-29 01:33:56
【问题描述】:

如果数据库中有记录,我正在尝试检查 CheckBoxGridView 中的某些行。假设我在一个类别中有产品 1、2、3、4,可用于包装的产品是 1 和 3。在我的 GridView 中,对于每个类别,我只选中了产品 1 和 3 的复选框,而不是所有该类别的产品。这是我设置GridView的方法:

<!-- Collapsible panel extender body -->
<asp:Panel ID="pBody1" runat="server" CssClass="cpBody">
    <asp:Label ID="lblBodyText1" runat="server" />
    <!-- Grid view to show products based on each category -->
    <asp:GridView ID="gvProduct" runat="server" AutoGenerateColumns="False" Width="998px" CellPadding="4" ForeColor="#333333" GridLines="None" ShowHeader="False" DataKeyNames="id">
        <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
        <Columns>
            <asp:TemplateField HeaderText="Select" ItemStyle-HorizontalAlign="Center">
                <ItemTemplate>
                    <asp:CheckBox ID="cbSelect" runat="server" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:BoundField DataField="name" HeaderText="Name" ItemStyle-Width="750px" />
            <asp:BoundField DataField="categoryName" HeaderText="Category" />
            <asp:BoundField DataField="inventoryQuantity" HeaderText="Quantity" />
        </Columns>
    </asp:GridView>
</asp:Panel>

从后面的代码中,我首先根据类别获取所有产品。我将其命名为 prodList。然后,我得到所有可用于包装的产品。我将其命名为 distSPUItemList。我遍历两个列表,如果它们的名称匹配,我得到行并选中复选框:

List<ProductPacking> prodList = new List<ProductPacking>();
//Get all products based on category
prodList = prodPackBLL.getAllProductByCategory(category);
gv.DataSource = prodList;
gv.DataBind();

List<DistributionStandardPackingUnitItems> distSPUItemList = new List<DistributionStandardPackingUnitItems>();
distSPUItemList = packBLL.getAllSPUItemByDistributionID(distributionID);
for (int i = 0; i < distSPUItemList.Count; i++)
{
    for (int j = 0; j < prodList.Count; j++)
    {
        GridView gvForCheckBox = (GridView)e.Item.FindControl("gvProduct") as GridView;
        foreach (GridViewRow gr in gvForCheckBox.Rows)
        {
            if (prodList[j].name == distSPUItemList[i].name)
            {
                CheckBox cb = (CheckBox)gr.Cells[0].FindControl("cbSelect");
                cb.Checked = true;
            }
        }
    }
}

但是,对于CheckBox,它只检查该类别中的所有产品,而不是检查 prodList 和 distSPUItemList 之间匹配的产品。这是为什么呢?

【问题讨论】:

  • 您的ProductPacking 类是否有一个布尔属性,表明它可用于打包?可以加一个吗?如果是这样,您可以在数据绑定期间设置复选框“已检查属性”。
  • 不,不,我想要做的是得到一份产品清单。我还得到了一份标准包装单位物品的清单。如果产品在特定配送的标准包装单元项目列表中,则该产品的复选框将被选中。这就是为什么我通过两个列表来匹配名称

标签: c# asp.net linq gridview checkbox


【解决方案1】:

我认为解决您的问题的最佳方法是确定是否应在数据绑定您的“gvProduct”控件之前检查此CheckBox。提前在Data Source 中设置此值将防止您以后必须重新访问GridView

如果这不是一个选项,下面的解决方案将起作用,但更笨拙,因为您必须重新访问 GridView 然后迭代其 Row 集合。

免责声明,在没有 VS2012 的情况下在我的脑海中完成,所以请原谅任何小的语法错误。我修改了您的代码以删除与此解决方案不特别相关的部分。首先,获取您的两个对象列表:

List<ProductPacking> prodList = prodPackBLL.getAllProductByCategory(category);
List<DistributionStandardPackingUnitItems> distSPUItemList = packBLL.getAllSPUItemByDistributionID(distributionID);

接下来,您可以使用简单的 LINQ 查询来比较对象列表,以查找名称属性等于 distSPUItemList 中的项目的 ProductPacking 对象。这会创建一个新集合,其中包含匹配的对象:

var available = // Start with prodList
                from a in prodList 
                // perform an inner-join between prodList and distSPUItemList only returning objects whose names match
                // (x => x.name == a.name) compares b.name to a.name, this is specifically what enforces that names match.
                from b in distSPUItemList.Where(x => x.name == a.name)
                // after inner joining is done, only select objects from prodList (we could select more things, but we only need these.)
                select a;

最后,您可以迭代 gridview 行并查看 GridView 中显示的 name 属性是否在可用于打包的产品列表中,如果是,请选中复选框。

GridView gvForCheckBox = (GridView)e.Item.FindControl("gvProduct") as GridView;
foreach (GridViewRow gr in gvForCheckBox.Rows)
{
    // query the available collection to see if it contains a ProductPacking object with a name equal to what is in the current GridView row.
    // I would recommend to match on a PK
    // disclaimer, matching on name may be a problem if two different products can have the same name.
    if (available.Where(x=>x.Name==gr.Cells[1].Text).Any())
    {
        CheckBox cb = (CheckBox)gr.Cells[0].FindControl("cbSelect");
        cb.Checked = true;
    }
}

【讨论】:

  • 什么是 (x => x.name == a.name) select a;是什么意思?
  • 我写这个解决方案是为了复制和替换您的三个嵌套 for 循环。你能试试我的第二个和第三个代码块,看看它是否有想要的结果吗?第一个代码块已经在您的代码中完成。
  • 这是 LINQ (msdn.microsoft.com/en-us/library/bb397919.aspx),它提供了用于查询 Lists 和 IEnumerables 等对象的语法。 “选择一个;”字面意思是从别名为“a”的列表中选择对象,即List&lt;ProductPacking&gt; prodList;
  • 是的,它可以工作,但我需要明确 LINQ 查询,以便将来可以使用它。我可以这样解释吗:listSPUItem 的循环项存储为 var x。然后,如果一个名称为 prodList 的循环项等于 var x 这是 listSPUItem 的循环项,那么我得到 a.name??对不起我的英语不好。
  • 我很高兴它成功了。我在 LINQ 代码中添加了一些 cmets。一个好的描述应该是“查找名称出现在 distSPUItemList 中的所有 ProductPacking 对象;从找到的那些 ProductPacking 对象中更新 GridView 的相应 CheckBox 以指示打包可用。”
猜你喜欢
  • 1970-01-01
  • 2020-12-23
  • 2013-10-31
  • 1970-01-01
  • 2015-01-26
  • 2014-04-16
  • 1970-01-01
  • 2016-06-05
  • 2023-03-30
相关资源
最近更新 更多