【问题标题】:Getting row index of checked row获取选中行的行索引
【发布时间】:2014-01-16 08:58:33
【问题描述】:

当我的gridview 中的checkbox 列被标记时,我正在尝试做,我得到行索引。我的gridview 在中继器中,当我设置gridview 时,我放了一个DataKeyNames

<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
                    <ItemTemplate>
<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 ItemStyle-HorizontalAlign="Center">
                                        <ItemTemplate>
                                            <asp:CheckBox ID="cbCheckRow" runat="server" />
                                        </ItemTemplate>
                                    </asp:TemplateField>
                                    <asp:BoundField DataField="name" HeaderText="Name" ItemStyle-Width="600px" />
                                    <asp:BoundField DataField="categoryName" HeaderText="Category" />
                                    <asp:TemplateField HeaderText="Quantity" ItemStyle-HorizontalAlign="Center">
                                        <ItemTemplate>
                                            <asp:TextBox ID="tbQuantity" runat="server" Width="60" Text='<%# DataBinder.Eval(Container.DataItem, "inventoryQuantity") %>'/>
                                        </ItemTemplate>
                                    </asp:TemplateField>

                                </Columns>
                            </asp:GridView>
                        </asp:Panel>
                        <asp:CollapsiblePanelExtender ID="cpe1" runat="server" TargetControlID="pBody1" CollapseControlID="pHeader1"
                            ExpandControlID="pHeader1" Collapsed="true" ImageControlID="imgArrows1"
                            CollapsedImage="~/Images/downarrow.jpg"
                            ExpandedImage="~/Images/uparrow.jpg" TextLabelID="lblHeaderText1" CollapsedText="Show"
                            ExpandedText="Hide" CollapsedSize="0"
                            ScrollContents="false">
                        </asp:CollapsiblePanelExtender>
                    </ItemTemplate>
                </asp:Repeater>
 <asp:LinkButton ID="lbnConfirm" runat="server" class="btn dark" style="float: right" OnClick="lbnConfirm_Click">Confirm</asp:LinkButton>

当我的lbnConfirmonclick 时,我执行此操作以获取行索引并将它们存储到列表中:

 protected void lbnConfirm_Click(object sender, EventArgs e)
    {
        GridView gv = (GridView)Repeater1.FindControl("gvProduct") as GridView;
        foreach (GridViewRow gr in gv.Rows)
        {
            CheckBox cb = (CheckBox)gr.Cells[0].FindControl("cbCheckRow");
            if (cb.Checked)
            {
                GridViewRow row = gv.SelectedRow;
                string prodID = this.gv.DataKeys[row].Value.ToString();
                List<DistributionStandardPackingUnitItems> distSPUList = new List<DistributionStandardPackingUnitItems>();
                //Store the prodIDs into list
            }

        }
    }

当我运行页面时,它在这一行告诉我object reference is not set to an instance

foreach (GridViewRow gr in gv.Rows)

还有这行的gv

string prodID = this.gv.DataKeys[row].Value.ToString(); 

告诉我gv 不包含缺少引用的定义。我以为我在上面的代码中声明了?

编辑部分:

       protected void lbnConfirm_Click(object sender, EventArgs e)
    {
        foreach (RepeaterItem item in Repeater1.Items)
        {
            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
            {
                Panel pnl = item.FindControl("pBody1") as Panel;
                GridView gv = pnl.FindControl("gvProduct") as GridView;
                foreach (GridViewRow gr in gv.Rows)
                {
                    CheckBox cb = (CheckBox)gr.Cells[0].FindControl("cbCheckRow");
                    if (cb.Checked)
                    {
                        string prodID = gv.DataKeys[gr.RowIndex].Value.ToString();
                        tempList.Add(prodID);
                        for (int count = 0; count < tempList.Count; count++)
                        {
                            lblTest.Text = tempList[count] + ",";
                        }
                    }
                }
            }
        }
    }

【问题讨论】:

    标签: c# asp.net gridview checkbox


    【解决方案1】:

    您的方法是正确的,但是您需要考虑更多的事情:

    1. 您必须遍历Repeater 的项目并在其中找到Panel 每个项目。

    2. 您必须在Panel 中找到GridView,而不是在Repeater 中。

    3. 您必须按RowIndex 查找DataKey 值,而不是按行。

    编辑:要测试,请在中继器外添加标签:

    <asp:Label ID="lblTest" runat="server" Text=""></asp:Label>
    

    还要更改代码以在标签中显示 Id。

    重写lbnConfirm_Click()方法后,应该如下所示:

    protected void lbnConfirm_Click(object sender, EventArgs e)
    {
        List<string> tempList = new List<string>();
        foreach (RepeaterItem item in Repeater1.Items)
        {
            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
            {
                Panel pnl = item.FindControl("pBody1") as Panel;
    
                GridView gv = pnl.FindControl("gvProduct") as GridView;
                foreach (GridViewRow gr in gv.Rows)
                {
                    CheckBox cb = (CheckBox)gr.Cells[0].FindControl("cbCheckRow");
                    if (cb.Checked)
                    {
                        //GridViewRow row = gv.SelectedRow;
                        string prodID =  gv.DataKeys[gr.RowIndex].Value.ToString();
                        List<DistributionStandardPackingUnitItems> distSPUList = new List<DistributionStandardPackingUnitItems>();
                        //Store the prodIDs into list
                        tempList.Add(prodID);                        
                    }
    
                }
            }
        }  
    
        lblTest.Text = string.Join(",", tempList);       
    }
    

    上面的代码在我的测试中运行良好!只是你必须小心不要在 Page_Load() 的回发时重新绑定转发器。

    希望对你有帮助!

    【讨论】:

    • 我已经添加了这些代码来测试prodID获取是否正确(再次检查编辑部分,抱歉)。但是,无论我检查哪些产品,它都会一直返回给我一个奇怪的值,因为我不知道这个值来自哪里。
    • 哦,是的,我忘了连接 prodID,这就是为什么它一直返回一个值而不是一个列表的原因。非常感谢!
    • 很高兴它有帮助:)
    • 但是,它会一遍又一遍地循环记录。假设我检查了产品 1、2、6、7。它返回我 1,1,2,1,2,6,1,2,6,7。我猜在第一次检查时,它会返回 1。在第二次检查时,它会返回 1,2,依此类推。我猜是因为我使用的是中继器和可折叠面板扩展器,这就是它不断循环播放的原因。有没有办法解决这个问题?
    • @Gwen - 我认为你的测试有一些问题,你不应该遍历循环内的列表。我为此添加了对我有用的测试代码。你能查一下吗?
    【解决方案2】:

    在 RowDataBound 事件中获取行索引:

     protected void gvProduct_RowDataBound(Object sender, GridViewRowEventArgs e)
        {
    
           if(e.commandName=="select")
           {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                int index = e.Row.RowIndex;
    
                CheckBox chk = (CheckBox)e.Row.FindControl("cbCheckRow"); 
                int code = Convert.ToInt32(this.gvProduct.DataKeys[e.Row.RowIndex].Value);
    
            }
         }
    
        }
    

    【讨论】:

    • 但是我怎么知道复选框列是否被选中?因为我应该将我的 lbnConfirm_onClick 中的所有代码移到这里?
    • 我已经编辑了我的答案...!!帮助您了解如何使用数据键获取值
    • 但是在 gvProduct 中,它告诉 not 不包含“gvProduct”的定义,并且没有接受第一个参数类型的扩展方法,我在上面的代码中遇到了同样的事情。另外,我在网格视图中没有按钮字段,所以我不能使用命令名称。它只是简单的复选框列
    • 你必须从 Gridview 属性中选择事件 RowDatabound
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2014-08-31
    • 2016-03-28
    • 2015-01-23
    • 1970-01-01
    相关资源
    最近更新 更多