实现GridView中点击超链接(非±符号)的展开/折叠功能
I’ll walk you through two practical approaches to achieve this: a client-side (jQuery) solution (for smooth, postback-free interactions) and a server-side (postback-based) solution (if you need to process server data when expanding/collapsing).
Client-Side Approach (jQuery)
This method avoids postbacks and delivers a responsive user experience. We’ll add hidden details rows and use jQuery to toggle their visibility when the link is clicked.
Step 1: Update GridView Markup
First, add CSS classes to the LinkButton and GridView rows for easier targeting:
<asp:GridView ID="grdrequisitions" runat="server" AutoGenerateColumns="false" AllowPaging="True" OnPageIndexChanging="grdrequisitions_PageIndexChanging" OnRowCommand="grdrequisitions_RowCommand" CssClass="table table-hover table-bordered table-striped table-page new-table" ShowHeaderWhenEmpty="True" PageSize="15" EmptyDataText="No records found" class="WordWrap" RowCssClass="main-row"> <!-- Add row class here --> <Columns> <asp:TemplateField> <ItemTemplate> <asp:CheckBox ID="chkRow" runat="server" AutoPostBack="True" OnCheckedChanged="ChkSelectChanged" onclick="CheckBoxCheck(this);" /> </ItemTemplate> </asp:TemplateField> <asp:BoundField DataField="WorkforcePlanStatus" HeaderText="Status" /> <asp:BoundField DataField="WorkforcePlanID" HeaderText="WFP ID" HtmlEncode="false" /> <asp:BoundField DataField="CRMOpportunityCode" HeaderText="O2R ID" /> <asp:BoundField DataField="DeliveryUnit" HeaderText="Delivery Unit" /> <asp:BoundField DataField="CustomerAccount" HeaderText="Account" /> <asp:TemplateField HeaderText="# Openings"> <ItemTemplate> <asp:LinkButton ID="lnkTotalHeadCount" Style="color: #0000b3;" runat="server" CausesValidation="false" CommandName="TotalHeadCount" Text='<%# Eval("TotalHeadCount") %>' CommandArgument='<%# Eval("WorkforcePlanID") %>' EnableTheming="False" CssClass="expand-collapse-link" <!-- Add link class here --> data-wfp-id='<%# Eval("WorkforcePlanID") %>'> </asp:LinkButton> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView>
Step 2: Add Code-Behind to Create Details Rows
Use the RowDataBound event to insert a hidden details row after each main row:
protected void grdrequisitions_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { // Create a new row for expanded details GridViewRow detailsRow = new GridViewRow(e.Row.RowIndex + 1, -1, DataControlRowType.DataRow, DataControlRowState.Normal); TableCell detailsCell = new TableCell(); // Span all columns (adjust to match your GridView's column count) detailsCell.ColumnSpan = grdrequisitions.Columns.Count; detailsCell.CssClass = "details-cell"; // Fetch and populate details content int wfpId = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "WorkforcePlanID")); detailsCell.Controls.Add(new LiteralControl(GetDetailsHtml(wfpId))); detailsRow.Cells.Add(detailsCell); detailsRow.CssClass = "details-row"; detailsRow.Style["display"] = "none"; // Hide by default // Insert the details row into the GridView table Table gridTable = e.Row.Parent as Table; gridTable.Rows.AddAt(e.Row.RowIndex + 1, detailsRow); } } // Helper method to generate details HTML private string GetDetailsHtml(int workforcePlanId) { // Replace this with your logic to load specific details for the WFP ID return $@" <div class='details-content'> <h5>Details for WFP ID: {workforcePlanId}</h5> <p>Add your expanded content here (e.g., nested GridView, additional fields, etc.)</p> </div>"; }
Step 3: Add jQuery and CSS
Include jQuery (if not already present) and add the toggle logic plus styling:
<!-- Add jQuery reference (place in your page's head or end of body) --> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script> $(document).ready(function() { // Handle click on expand/collapse link $('.expand-collapse-link').on('click', function(e) { e.preventDefault(); // Stop default postback var $link = $(this); var $mainRow = $link.closest('.main-row'); var $detailsRow = $mainRow.next('.details-row'); // Toggle visibility of the details row $detailsRow.toggle(); // Optional: Style the link to indicate expanded state $link.toggleClass('expanded'); }); }); </script> <style> .details-row { background-color: #f8f9fa; } .details-content { padding: 15px; } .expand-collapse-link.expanded { font-weight: bold; color: #007bff; } </style>
Server-Side Approach (Postback-Based)
If you need to process server-side data when expanding/collapsing, use this method. It uses postbacks and ViewState to track expanded rows.
Step 1: Update GridView Markup
Add a hidden panel for details in each row:
<asp:GridView ID="grdrequisitions" runat="server" AutoGenerateColumns="false" AllowPaging="True" OnPageIndexChanging="grdrequisitions_PageIndexChanging" OnRowCommand="grdrequisitions_RowCommand" OnRowDataBound="grdrequisitions_RowDataBound" <!-- Add RowDataBound event --> CssClass="table table-hover table-bordered table-striped table-page new-table" ShowHeaderWhenEmpty="True" PageSize="15" EmptyDataText="No records found" class="WordWrap"> <Columns> <!-- Existing columns here --> <asp:TemplateField HeaderText="# Openings"> <ItemTemplate> <asp:LinkButton ID="lnkTotalHeadCount" Style="color: #0000b3;" runat="server" CausesValidation="false" CommandName="TotalHeadCount" Text='<%# Eval("TotalHeadCount") %>' CommandArgument='<%# Eval("WorkforcePlanID") %>' EnableTheming="False"> </asp:LinkButton> </ItemTemplate> </asp:TemplateField> <!-- Add details panel --> <asp:TemplateField> <ItemTemplate> <asp:Panel ID="pnlDetails" runat="server" Visible="false" CssClass="details-panel"> <p>Details for WFP ID: <%# Eval("WorkforcePlanID") %></p> <!-- Add your expanded content here --> </asp:Panel> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView>
Step 2: Add Code-Behind Logic
Track expanded rows in ViewState and toggle panel visibility:
protected void grdrequisitions_RowCommand(object sender, GridViewCommandEventArgs e) { if (e.CommandName == "TotalHeadCount") { int wfpId = Convert.ToInt32(e.CommandArgument); List<int> expandedIds = ViewState["ExpandedIds"] as List<int> ?? new List<int>(); // Toggle expanded state for this WFP ID if (expandedIds.Contains(wfpId)) { expandedIds.Remove(wfpId); } else { expandedIds.Add(wfpId); } ViewState["ExpandedIds"] = expandedIds; grdrequisitions.DataBind(); // Rebind to update visibility } } protected void grdrequisitions_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { int wfpId = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "WorkforcePlanID")); Panel pnlDetails = e.Row.FindControl("pnlDetails") as Panel; List<int> expandedIds = ViewState["ExpandedIds"] as List<int> ?? new List<int>(); // Show/hide panel based on expanded state pnlDetails.Visible = expandedIds.Contains(wfpId); } }
Key Notes:
- For the client-side approach, ensure jQuery is included in your page.
- Adjust the
colspanvalue in the client-side details row to match the number of columns in your GridView (7 in your provided markup). - Customize the
GetDetailsHtmlmethod (client-side) or the details panel (server-side) to display your specific expanded content. - Since you can’t use +/- signs, use styling (like bold text or color changes) to indicate the link’s expanded state.
内容的提问来源于stack exchange,提问作者Ashok kumar Reddy

