You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:15:19