GridView模板列中TextBox的OnTextChanged事件更新后丢失下一个控件焦点
解决GridView模板列TextBox回发后焦点丢失问题
问题分析
UpdatePanel内GridView的TemplateField中,TextBox开启AutoPostBack="true"触发OnTextChanged事件后,页面局部刷新会导致焦点丢失,Tab操作会回到第一行控件。本质是回发后DOM重新渲染,原有焦点状态未被保留。
解决方案
通过后台记录触发回发的TextBox位置,回发完成后自动将焦点定位到同一行的下一个控件,或通过前端脚本在回发前后处理焦点逻辑,以下是两种可行方案:
方案一:后台代码控制焦点跳转
修改OnTextChanged方法,在处理业务逻辑后,定位同一行的下一个TextBox,通过ScriptManager注册脚本设置焦点:
Protected Sub OnTextChanged(sender As Object, e As EventArgs) Dim textBox As TextBox = CType(sender, TextBox) Dim row As GridViewRow = CType(textBox.NamingContainer, GridViewRow) ' 执行原有业务逻辑 UpdateTotalValue(Val(textBox.Text)) ' 根据当前TextBox的ID,定位同一行的下一个目标控件 Dim nextTextBox As TextBox = Nothing Select Case textBox.ID Case "txtAmount" nextTextBox = CType(row.FindControl("txtQty"), TextBox) Case "txtQty" ' 若当前是最后一列,可跳转到下一行的第一个TextBox If row.RowIndex < GridView1.Rows.Count - 1 Then nextTextBox = CType(GridView1.Rows(row.RowIndex + 1).FindControl("txtAmount"), TextBox) End If ' 可继续扩展其他列的跳转逻辑 End Select ' 注册脚本设置焦点(仅在UpdatePanel局部回发时生效) If nextTextBox IsNot Nothing Then ScriptManager.RegisterStartupScript(Me, Me.GetType(), "SetFocus", $"document.getElementById('{nextTextBox.ClientID}').focus();", True) End If End Sub
方案二:前端脚本自动处理焦点(无需修改后台)
利用ASP.NET AJAX的PageRequestManager对象,在回发前后记录并恢复焦点,自动跳转到下一个控件:
在ASPX页面添加以下脚本:
<script type="text/javascript"> var lastFocusedId; // 回发开始前记录当前焦点控件ID Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(function(sender, args) { lastFocusedId = document.activeElement?.id; }); // 回发完成后定位下一个控件并设置焦点 Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args) { if (!lastFocusedId) return; var currentControl = document.getElementById(lastFocusedId); if (!currentControl) return; // 尝试获取同一行的下一个TextBox var nextControl = currentControl.parentElement.nextElementSibling?.querySelector('input[type="text"]'); // 若当前是行内最后一个控件,跳转到下一行第一个TextBox if (!nextControl) { var currentRow = currentControl.closest('tr'); var nextRow = currentRow?.nextElementSibling; nextControl = nextRow?.querySelector('input[type="text"]'); } if (nextControl) nextControl.focus(); }); </script>
关键注意事项
- 后台方案中必须使用
ScriptManager.RegisterStartupScript,而非普通的ClientScript,确保脚本能注入到UpdatePanel的局部更新DOM中。 - 前端方案依赖ASP.NET AJAX框架,需确保页面已添加
<asp:ScriptManager>控件。
内容的提问来源于stack exchange,提问作者Sixthsense
相关产品推荐
相关产品推荐

