C# 选中Gridview中的复选框

C# 选中Gridview中的复选框,c#,asp.net,linq,gridview,checkbox,C#,Asp.net,Linq,Gridview,Checkbox,如果数据库中有记录,我试图选中GridView中某些行的复选框。假设我有一个类别中的产品1,2,3,4,可用于包装的产品是1和3。在我的GridView中,对于每个类别,我只选中了产品1和3的复选框,而不是该类别中的所有产品。下面是我如何设置GridView的: 从后面的代码中,首先我得到了基于类别的所有产品。我把它命名为prodList。然后,我得到所有可用于包装的产品。我把它命名为distSPUItemList。我循环浏览这两个列表,如果它们的名称匹配,我将获得该行并选中复选框: List&

如果数据库中有记录,我试图选中GridView中某些行的复选框。假设我有一个类别中的产品1,2,3,4,可用于包装的产品是1和3。在我的GridView中,对于每个类别,我只选中了产品1和3的复选框,而不是该类别中的所有产品。下面是我如何设置GridView的:

从后面的代码中,首先我得到了基于类别的所有产品。我把它命名为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;
            }
        }
    }
}

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

我认为解决问题的最佳方法是确定在数据绑定产品控件之前是否应选中此复选框。提前在数据源中设置此值将防止以后重新访问GridView

如果这不是一个选项,下面的解决方案将起作用,但由于您必须重新访问GridView,然后迭代它的行集合,因此会更加笨拙

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

List<ProductPacking> prodList = prodPackBLL.getAllProductByCategory(category);
List<DistributionStandardPackingUnitItems> distSPUItemList = packBLL.getAllSPUItemByDistributionID(distributionID);
最后,您可以迭代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;
    }
}

ProductPacking类是否具有布尔属性,指示它可用于打包?你能添加一个吗?如果是这样,您可以在数据绑定期间设置checkbox Checked属性。我还得到了一份标准包装单。如果产品在特定分销的标准包装单位项目清单内,则将选中该产品的复选框。这就是为什么我在两个列表中都删掉以匹配名称x=>x.name==a.name选择a;意思是?我写这个解决方案是为了复制和替换三个嵌套for循环。你能试试我的第二和第三个代码块,看看它是否有理想的结果吗?您的代码中已经完成了第一个代码块。这是LINQ,它为查询列表和IEnumerables等对象提供语法。选择一个;表示从别名为a的列表中选择对象,该列表为列表prodList;是的,它可以工作,但是我需要清楚LINQ查询,以便将来可以使用它。我可以这样解释:listSPUItem的循环项存储为VARx。然后如果a的名称为prodList的循环项等于var x,它是listSPUItem的循环项,那么我得到a.name??对不起,我的英语不好。我很高兴它起作用了。我在LINQ代码中添加了一些注释。一个好的描述是找到名称出现在distSPUItemList中的所有ProductPacking对象;从找到的那些ProductPacking对象中,更新GridView的相应复选框以指示打包可用。
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 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;
    }
}