我有一个包含文本框的GridView<asp:TemplateField />,GridView位于 AJAX 更新面板中。使用TextChanged事件处理GridView中的文本框,当用户在模板字段中输入内容时,该事件将触发。到目前为止,这还可以,但问题是,一旦我在更新后退出文本框,光标就会失去焦点,而不是移动到下一个控件。
当我再次按Tab键时,它从模板字段的第一行第一个单元格开始。如何处理这个问题?如何使光标移动到下一个字段而不失去当前行的焦点。
ASPX代码
<asp:TemplateField HeaderText="Amount"
HeaderStyle-Width="255" ItemStyle-Width="255">
<ItemTemplate>
<asp:TextBox ID="txtAmount" runat="server" OnTextChanged = "OnTextChanged" AutoPostBack = "true"
Visible="TRUE" Height="30">
</asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Qty"
HeaderStyle-Width="255" ItemStyle-Width="255">
<ItemTemplate>
<asp:TextBox ID="txtQty" runat="server" OnTextChanged = "OnTextChanged" AutoPostBack = "true"
Visible="TRUE" Height="30">
</asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
etc.,
代码隐藏
Protected Sub OnTextChanged(sender As Object, e As EventArgs)
Dim textBox As TextBox = CType(sender, TextBox)
Dim id As String = textBox.ID
UpdateTotalValue(Val(textBox.Text))
End Sub
1条答案
按热度按时间wdebmtf21#
这可能会很困难,因为如果你重新绑定gv,那么你会导致回发。即使引入了更新面板,我们仍然会得到一个叫做部分回发的东西。这意味着页面类被重新创建,页面加载再次启动,你的代码在后面运行。所以,虽然这看起来像是没有回发发生,这在某种程度上是在愚弄你。虽然更新面板确实/可以解决许多浏览器重新绘制的问题,但请记住,UP仍然是一种回发,只是一种有限的回发。(因此,页面生命周期和往返确实会发生-只是更有限,但不是"零")。
事实上,正确的说法是"部分回邮"。
您没有显示UpdateTotalValue代码的功能,但是如果它重新绑定了GV,那么您就有了一个正在被重新加载的GV。
如果你的onchange/update代码只修改了当前行,然后可能重新计算了最终的总和,但是没有重新绑定gv,那么这可能会工作得更好。
如果没有,那么我们可能不得不引入ajax,或者一些客户端js代码。
我想,这在很大程度上取决于UpdateTotal例程做什么。
如果你可以运行/得到gv的总数,插入一些总值(比如在gv的底部,而不是重新绑定gv,那么你可能没问题)。
然而,如果你重新绑定了gv,那么我们可能不得不尝试加入一些设置焦点的代码,但是这样的代码往往有点"hacky"。
编辑:因此,GV未被重新绑定
我成功地使用了两种方法。
《易》:
我所做的是在文本框上执行一个控件SetFocus。这意味着用户输入一个值,点击Tab,所有内容都更新了,但焦点返回到文本框。实际上,如果用户在GV中点击Tab,则Tab起作用-(几乎就像在Excel工作表中跳来跳去)。但是,如果他们输入/更改那个值,那么你会发现你必须点击Tab键2次。通常,用户并不在意,因为他们只改变了一个值,然后继续。但是,假设鼠标点击了下面几行的文本框,他们将不得不点击两次。
我建议以上,因为这是最少的努力和接近零代码更改您所拥有的。
然而,经过时间和乱搞尝试各种方法?
我发现使用一些客户端JavaScript会带来更好的用户体验,因此标签也不会搞砸。总的来说,代码总量大致相同,甚至可能比服务器端代码少一点。然而,不利的一面是我们现在必须编写JavaScript代码,这可能会很"痛苦",或者至少比你发布的Simple + Clean + Easy服务器端代码更难。
I'll later today post both samples as a vb.net gv. (set focus, and 100% client JavaScript. With the JavaScript, then that means we can dump the update panel. (not a huge deal, but it does reduce page post-backs, and the user experience is much better).
Edit2:设置焦点,100%服务器端代码。
好的,我们能做的就是在运行代码之后,重新设置控件的焦点。
在本例中,我们有2列(Number of Nights X Price)用于酒店房间列表。
因此,有2列需要"更新" CURRENT行的数学运算,然后当然还要更新GV底部的总计。
因此,我们有这样的标记:
要加载的代码如下:
我们有一套舞蹈要表演给萨姆看
这一点:
好的,现在我们看到了这个:
我将跳过第一行(左右),然后更改一个值,注意光标确实停留在原地。
所以这个:
因此,技巧很简单,只需使用control.SetFocus。
因此,如果我更改"夜晚",则会将焦点设置为"价格"。
如果更改价格,我会将焦点设置为"下一行"和"夜"。
所以,这个代码:
因为行计算是针对2个值的,所以我将其分解为一个名为rowcalc的例程(这样两个文本框都可以调用同一个例程)。
这个
所以,它不是完美的,但它不是所有的坏如果一个用户改变了一个值,但然后代替制表符决定使用鼠标,那么他们将在大多数情况下必须点击两次,因为失去焦点将触发我们的计算代码,然后设置焦点(强制用户再次点击,如果使用鼠标点击一行)。
不过,上面的效果还不错。
我出去休息一下,但是当我回来的时候,我们可以尝试/看看上面同样的JavaScript示例。js示例稍微好一点,因为我们根本没有使用post-back,所以焦点和单击(鼠标)不会变得混乱。