我创建了一个小脚本来保留异步回发期间的焦点元素,并且在通过asp:Repeater内部生成的控件进行选项卡时,除之外它完全正常,其中完整回发< / em>由于一些神秘的原因被触发。这是一个简明的样本:
<%@ Page Language="C#" EnableEventValidation="false" %>
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<script runat="server">
public IEnumerable<int> Measurements_GetData()
{
return new[] { 123, 328, 1099 };
}
</script>
</head>
<body>
<form method="post" runat="server">
<asp:ScriptManager runat="server" />
<asp:UpdatePanel runat="server">
<ContentTemplate>
<h1>OK</h1>
<div>
<asp:TextBox ID="Measurement1" runat="server" Text="123" AutoPostBack="true" />
</div>
<div>
<asp:TextBox ID="TextBox1" runat="server" Text="328" AutoPostBack="true" />
</div>
<div>
<asp:TextBox ID="TextBox2" runat="server" Text="1099" AutoPostBack="true" />
</div>
<h1>Not OK</h1>
<asp:Repeater ID="Measurements" runat="server" SelectMethod="Measurements_GetData" ItemType="System.Int32">
<ItemTemplate>
<div>
<asp:TextBox ID="Measurement" runat="server" AutoPostBack="true" Text="<%# Item %>" />
</div>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
</form>
<script type="text/javascript">
(function () {
var focusedElementId = "";
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(function (source, args) {
// re-focus element, if any selected prior to postback
if (focusedElementId !== "") {
document.getElementById(focusedElementId).focus();
console.log("focus:" + focusedElementId);
}
});
prm.add_pageLoading(function (source, args) {
var fe = document.activeElement;
focusedElementId = fe !== null ? fe.id : "";
});
})();
</script>
</body>
</html>
此示例显示工作和非工作行为。如果单击第一个文本框,请将值,选项卡更改为下一个,将值更改为选项卡,然后将选项卡正确保留到最后一个元素,并且可以在JS控制台中查看保留的焦点元素的进度。
现在,如果您观看JS控制台并单击转发器生成的标记中的第一个文本输入(不正常部分),请更改然后选项卡,再次更改选项卡,您可以看到焦点在最后一个控件上丢失,因为完整触发回发(清除JS控制台)。
这里发生了什么?看起来它必须是一个Web表单错误,否则我无法理解它。如果是错误,是否有解决方法?
答案 0 :(得分:1)
正如我所怀疑的,这是ASP.NET Web表单中的一个已知问题。它是由ASP.NET 4.0中的ClientIDMode更改引起的。 MS发布了some workarounds here。
如果您不关心生成的控件ID,最简单的解决方案似乎是reverting to pre-ASP.NET 4.0 behaviour by setting:
<pages ClientIDMode="AutoID" /
web.config中的。
答案 1 :(得分:0)
它看起来不像是一个bug,但是你的JavaScript函数在某种程度上是PostBack的原因。如果完全删除它,TextBoxes就会按照它们的行为进行操作。您的脚本绑定的TextBox之间可能不匹配(仅在首次加载页面时触发)和在异步回发后在Repeater内重新生成的TextBox.
如果您注册了Async PostBack的所有TextBox,它们将再次运行。
protected void Page_Load(object sender, EventArgs e)
{
foreach (RepeaterItem item in Measurements.Items)
{
TextBox tb = item.FindControl("Measurement") as TextBox;
ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(tb);
}
}