如何选中UpdatePanel嵌套GridView的行并加载数据到同页面Div
问题描述
需求:实现搜索功能,将搜索结果展示在可点击行的GridView中;点击行后提取该行信息,在同页面的新Div中展示,以便添加该行的专属信息。
当前错误:点击GridView行时出现“所有标头已发送”错误。
前端ASPX代码
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server"> <div class="wrapperHistoricalData"> <fieldset style="margin-bottom:5px;margin-top:10px;border-color:#efefef;"> <legend>Search</legend> <%-- <asp:UpdatePanel ID="uPanelTop" runat="server" > <ContentTemplate>--%> <div class="divFloatLeft"> <asp:TextBox ID="txtStudentFirstName" runat="server" placeholder="First Name or ID" ></asp:TextBox> <asp:TextBox ID="txtStudentLastName" runat="server" placeholder="Last Name" ></asp:TextBox> <asp:DropDownList ID="ddlClinicalType" runat="server" DataTextField="ClinicalTypeDesc" DataValueField="ClinicalTypeID" /> <asp:Button ID="btnSearch" runat="server" Text="Search" OnClick="btnSearch_Click" /> </div> <asp:RequiredFieldValidator ID="rfvClinicalType" runat="server" ControlToValidate="ddlClinicalType" InitialValue="" ErrorMessage="Please select a Clinical option!" ForeColor="Red" Style="margin-left: 25px;"/> <%-- </ContentTemplate> </asp:updatePanel>--%> </fieldset> </div> <div class="wrapperHistoricalData"> <asp:updatePanel ID="uPanelData" runat="server" > <ContentTemplate> <asp:GridView ID="gvHistoricalData" runat="server" AutoGenerateColumns="false" AllowPaging="True" AllowSorting="True" CssClass="DataEntryGridView" RowStyle-CssClass="GvGrid" OnRowDataBound="gvHistoricalData_RowDataBound" OnRowCommand="gvHistoricalData_RowCommand"> <RowStyle CssClass="rowMain" /> <AlternatingRowStyle CssClass="rowAlt" /> <HeaderStyle CssClass="rowHeader" width="100px"/> <Columns> <asp:TemplateField HeaderText="Name" ItemStyle-HorizontalAlign="Center" > <ItemStyle CssClass="noBorder"/> <ItemTemplate> <asp:Label runat="server" ID="lblName" Text='<%# Eval("FullName") %>' CssClass="StudentName" /> </ItemTemplate> </asp:TemplateField> </Columns> <AlternatingRowStyle BackColor="White" ForeColor="#284775" /> <EditRowStyle BackColor="#999999" /> <FooterStyle BackColor="#5D7B9D" ForeColor="White" Font-Bold="True" /> <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" Font-Size="15px" /> <PagerStyle CssClass="UserMaintUsersPager" BackColor="#284775" ForeColor="White" HorizontalAlign="Center" /> <RowStyle BackColor="#F7F6F3" ForeColor="#333333" /> <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" /> <SortedAscendingCellStyle BackColor="#E9E7E2" /> <SortedAscendingHeaderStyle BackColor="#506C8C" /> <SortedDescendingCellStyle BackColor="#FFFDF8" /> <SortedDescendingHeaderStyle BackColor="#6F8DAE" /> </asp:GridView> </ContentTemplate> </asp:updatePanel> </div> <div class="divInput" id="divtest"> <div> <--- this sint done being built yet but the information will be in here with more input boxes ----> <asp:Label runat="server" ID="lbltest" Text="yeah"></asp:Label> </div> </div> </asp:Content>
后端C#代码
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { getClinicalTypes(); } // Restore selected row color after postback HighlightSelectedRow(); } protected void Search(string fname, string lname, string clinicalType) { List<StudentInfo> studInfo = new List<StudentInfo>(); if((Regex.IsMatch(fname, @"\d")) ) { studInfo = CTStudentSearch.ListSearch("I", fname, "", clinicalType); } else { studInfo = CTStudentSearch.ListSearch("N", fname, lname, clinicalType); } gvHistoricalData.DataSource = studInfo; gvHistoricalData.DataBind(); } protected void btnSearch_Click(object sender, EventArgs e) { string searchText = ""; string fname = (!string.IsNullOrWhiteSpace(txtStudentFirstName.Text)) ? txtStudentFirstName.Text : ""; string lname = (!string.IsNullOrWhiteSpace(txtStudentLastName.Text)) ? txtStudentLastName.Text : ""; bool clinicalTypeChecked = (ddlClinicalType.SelectedIndex > 0) ? true : false; string clinicalType = null; if (clinicalTypeChecked == true) { clinicalType = ddlClinicalType.SelectedValue; Search(fname, lname, clinicalType); } } protected void gvHistoricalData_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { e.Row.Attributes.Add("onMouseOver", "this.originalstyle=this.style.backgroundColor;this.style.backgroundColor='#5D7B9D';this.style.cursor='pointer';"); e.Row.Attributes.Add("OnMouseOut", "this.style.backgroundColor=this.originalstyle;"); // Updated script to prevent row selection if clicking inside an input, button, or link //string script = "if(event.srcElement && (event.srcElement.tagName.toLowerCase() === 'input' || event.srcElement.tagName.toLowerCase() === 'button' || event.srcElement.tagName.toLowerCase() === 'a')) return;"; //e.Row.Attributes["onclick"] = script + Page.ClientScript.GetPostBackClientHyperlink(gvHistoricalData, "Select$" + e.Row.RowIndex); // Add a hidden button inside the row to trigger postback LinkButton lb = new LinkButton(); lb.CommandName = "Select"; lb.CommandArgument = e.Row.RowIndex.ToString(); lb.Style["display"] = "none"; // Hide the button e.Row.Cells[0].Controls.Add(lb); // Add OnClientClick event lb.OnClientClick = "return showInputDiv(); "; // Optionally, set a data attribute to store the row index lb.Attributes["data-row-index"] = e.Row.RowIndex.ToString(); e.Row.Cells[0].Controls.Add(lb); } }
问题原因与修复方案
1. 重复添加LinkButton触发异常
在gvHistoricalData_RowDataBound方法中,你两次执行e.Row.Cells[0].Controls.Add(lb);,重复添加同一个控件会破坏页面控件树结构,引发“所有标头已发送”错误。
修复:删除其中一次添加操作,保留一行即可。
2. 未实现RowCommand处理逻辑
GridView绑定了OnRowCommand事件,但后端没有对应的处理方法,无法响应行点击请求,也会引发异常。
修复:添加以下代码实现行点击后的信息提取与Div更新:
protected void gvHistoricalData_RowCommand(object sender, GridViewCommandEventArgs e) { if (e.CommandName == "Select") { int rowIndex = Convert.ToInt32(e.CommandArgument); GridViewRow row = gvHistoricalData.Rows[rowIndex]; // 提取行内学生姓名 string studentName = ((Label)row.FindControl("lblName")).Text; // 更新Div中的显示内容 lbltest.Text = $"选中的学生:{studentName}"; // 显示目标Div(如果默认隐藏) divtest.Style["display"] = "block"; } }
3. 客户端函数未定义
LinkButton的OnClientClick调用了showInputDiv(),但前端未定义该函数,会导致脚本错误并中断回发流程。
修复:在ASPX页面末尾添加该JavaScript函数:
<script type="text/javascript"> function showInputDiv() { // 客户端显示目标Div document.getElementById('divtest').style.display = 'block'; return true; // 确保回发正常执行 } </script>
4. 可选优化:简化行点击触发逻辑
无需手动添加隐藏LinkButton,直接为行绑定回发脚本更简洁,同时避免控件重复添加问题:
protected void gvHistoricalData_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { e.Row.Attributes.Add("onMouseOver", "this.originalstyle=this.style.backgroundColor;this.style.backgroundColor='#5D7B9D';this.style.cursor='pointer';"); e.Row.Attributes.Add("OnMouseOut", "this.style.backgroundColor=this.originalstyle;"); // 直接绑定行点击回发脚本 e.Row.Attributes["onclick"] = Page.ClientScript.GetPostBackClientHyperlink(gvHistoricalData, "Select$" + e.Row.RowIndex); } }
内容的提问来源于stack exchange,提问作者ghostfly
相关产品推荐
相关产品推荐

