__doPostBack 仅当页面上有 LinkButton、Calendar 或 WizardStep 控件时才有效
__doPostBack only works if there is a LinkButton, Calendar or WizardStep control on the page
我发现了 __doPostBack 的问题并找到了解决方法。我正在寻求原因的解释 and/or 比我的工作更好的解决方案。
场景:
我有一个下拉菜单,其中填充了这些值; “-Select-”、"One" & "Two"。如果用户选择 "One" 则执行客户端脚本。如果用户选择 "Two" 则执行服务器端脚本。
问题:
客户端脚本通过调用 __doPostBack 启动 postback。但是,除非页面上还有 LinkButton、Calendar 或 WizardStep 控件,否则实际上不会发生 post 返回。我实际上浏览了 Visual Studio 工具箱中的所有标准工具并测试了它们。它必须是这三个之一。
解决方法:
添加一个 link 按钮,由一个 span 包围,显示设置为 none.
<span style="display:none;">
<asp:LinkButton ID="LinkButton1" runat="server">LinkButton</asp:LinkButton>
</span>
问题: 有人可以对此行为提供解释或提供比我的 "Work Around" 更好的修复方法吗?
来源-Javascript(我放在head标签之间)
<script language="javascript" type="text/javascript">
function DropDownList1_change(elementRef) {
var selectedIndex = elementRef.selectedIndex;
if (selectedIndex > 0) {
var selectedValue = elementRef.options[selectedIndex].value;
if (selectedValue == "One") {
alert("Because you selected 'One', special javascript code will be executed");
// Special javascript code goes here
return;
}
else if (selectedValue == "Two") {
// Special server code gets executed on server DropDownList1_SelectedIndexChanged
__doPostBack('DropDownList1', '');
}
}
}
</script>
来源 - ASPX 控件
<asp:DropDownList ID="DropDownList1" runat="server" onchange="DropDownList1_change(this)" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem>-Select-</asp:ListItem>
<asp:ListItem>One</asp:ListItem>
<asp:ListItem>Two</asp:ListItem>
</asp:DropDownList>
<br />
<!-- For some unknown reason __doPostBack only works if there is a LinkButton, Calendar or WizardStep control on the page -->
<span style="display:none;">
<asp:LinkButton ID="LinkButton1" runat="server">LinkButton</asp:LinkButton>
</span>
Time of last Post Back: <asp:Label ID="Label1" runat="server"></asp:Label><br />
Time of OnSelectedIndexChanged: <asp:Label ID="Label2" runat="server"></asp:Label>
来源 - 代码隐藏
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToLongTimeString();
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
Label2.Text = DateTime.Now.ToLongTimeString();
}
其他资源 - 我在 post 解决这个问题后找到了以下文章。这是一篇非常古老的 Microsoft 文章,也是我发现的唯一一篇提到 DropDowns、return values & postbacks 特定限制的 Microsoft 文章。我没有深入研究他们的解决方案,也不确定时间是否允许我这样做。主要是 post 万一我的解决方案失败或对其他人不起作用。
Intuitively you might think adding a confirm dialog box for a
DropDownList is identical to adding such a dialog box for a Button Web
control. That is, simply set the DropDownList's client-side onchange
attribute to something like: return confirm(...);. using:
DropDownListID.Attributes("onchange") = "return confirm(...);"
Unfortunately, this won't work as desired because an AutoPostBack
DropDownList's onchange attribute will be set to a bit of JavaScript
that causes a postback, namely a call to the client-side __doPostBack
function. When setting the onchange attribute programmatically
yourself, the end result is that the rendered client-side onchange
event handler has both your code and the call to __doPostBack:
文章较长,搜索"Confirmation with AutoPostBack DropDownLists"
有2种解法。
解决方案一:
work around 比添加被隐藏的 span 标签包围的 link 按钮更好的方法是将以下内容添加到页面加载事件。这确保函数 __doPostBack 可用。
protected void Page_Load(object sender, EventArgs e)
{
Page.ClientScript.GetPostBackEventReference(this, string.Empty);
}
仅当窗体中的控件需要它执行回发时,才会生成函数 __doPostBack
。这包括 LinkButton 等控件和 AutoPostBack
设置为 true
的其他控件。事实上,只有 Button 和 ImageButton 控件可以在没有 __doPostBack
的情况下执行回发(参见 this article)。例如,我们可以在 HTML 输出中看到 LinkButton 是这样呈现的:
<a id="lnk" href="javascript:__doPostBack('lnk','')">My link</a>
解决方案 2: 下面的方法在不使用 __doPostBack. 的情况下实现了同样的效果
在本例中,您可以为 DropDownList 设置 AutoPostBack="true"
:
<asp:DropDownList AutoPostBack="true" onchange="if (!confirmPostBack(this)) return false;" ... >
当您想阻止回发时,onchange
事件处理程序将 return false
。 Javascript 函数可能是这样的:
function confirmPostBack(ddl)
{
if (condition) {
...
return true;
}
else {
...
return false;
}
}
重要:onchange
事件处理程序不应该 return 任何允许回发发生的东西。您可以使用以下语法:
onchange="if (!confirmPostBack(this)) return false;"
由于问题中提到的文章中可能解释的原因,以下语法不起作用。返回 true
仍然会阻止回发。
onchange="return confirmPostBack(this);" // Does not work!
我发现了 __doPostBack 的问题并找到了解决方法。我正在寻求原因的解释 and/or 比我的工作更好的解决方案。
场景: 我有一个下拉菜单,其中填充了这些值; “-Select-”、"One" & "Two"。如果用户选择 "One" 则执行客户端脚本。如果用户选择 "Two" 则执行服务器端脚本。
问题: 客户端脚本通过调用 __doPostBack 启动 postback。但是,除非页面上还有 LinkButton、Calendar 或 WizardStep 控件,否则实际上不会发生 post 返回。我实际上浏览了 Visual Studio 工具箱中的所有标准工具并测试了它们。它必须是这三个之一。
解决方法: 添加一个 link 按钮,由一个 span 包围,显示设置为 none.
<span style="display:none;">
<asp:LinkButton ID="LinkButton1" runat="server">LinkButton</asp:LinkButton>
</span>
问题: 有人可以对此行为提供解释或提供比我的 "Work Around" 更好的修复方法吗?
来源-Javascript(我放在head标签之间)
<script language="javascript" type="text/javascript">
function DropDownList1_change(elementRef) {
var selectedIndex = elementRef.selectedIndex;
if (selectedIndex > 0) {
var selectedValue = elementRef.options[selectedIndex].value;
if (selectedValue == "One") {
alert("Because you selected 'One', special javascript code will be executed");
// Special javascript code goes here
return;
}
else if (selectedValue == "Two") {
// Special server code gets executed on server DropDownList1_SelectedIndexChanged
__doPostBack('DropDownList1', '');
}
}
}
</script>
来源 - ASPX 控件
<asp:DropDownList ID="DropDownList1" runat="server" onchange="DropDownList1_change(this)" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem>-Select-</asp:ListItem>
<asp:ListItem>One</asp:ListItem>
<asp:ListItem>Two</asp:ListItem>
</asp:DropDownList>
<br />
<!-- For some unknown reason __doPostBack only works if there is a LinkButton, Calendar or WizardStep control on the page -->
<span style="display:none;">
<asp:LinkButton ID="LinkButton1" runat="server">LinkButton</asp:LinkButton>
</span>
Time of last Post Back: <asp:Label ID="Label1" runat="server"></asp:Label><br />
Time of OnSelectedIndexChanged: <asp:Label ID="Label2" runat="server"></asp:Label>
来源 - 代码隐藏
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToLongTimeString();
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
Label2.Text = DateTime.Now.ToLongTimeString();
}
其他资源 - 我在 post 解决这个问题后找到了以下文章。这是一篇非常古老的 Microsoft 文章,也是我发现的唯一一篇提到 DropDowns、return values & postbacks 特定限制的 Microsoft 文章。我没有深入研究他们的解决方案,也不确定时间是否允许我这样做。主要是 post 万一我的解决方案失败或对其他人不起作用。
Intuitively you might think adding a confirm dialog box for a DropDownList is identical to adding such a dialog box for a Button Web control. That is, simply set the DropDownList's client-side onchange attribute to something like: return confirm(...);. using: DropDownListID.Attributes("onchange") = "return confirm(...);" Unfortunately, this won't work as desired because an AutoPostBack DropDownList's onchange attribute will be set to a bit of JavaScript that causes a postback, namely a call to the client-side __doPostBack function. When setting the onchange attribute programmatically yourself, the end result is that the rendered client-side onchange event handler has both your code and the call to __doPostBack:
文章较长,搜索"Confirmation with AutoPostBack DropDownLists"
有2种解法。
解决方案一: work around 比添加被隐藏的 span 标签包围的 link 按钮更好的方法是将以下内容添加到页面加载事件。这确保函数 __doPostBack 可用。
protected void Page_Load(object sender, EventArgs e)
{
Page.ClientScript.GetPostBackEventReference(this, string.Empty);
}
仅当窗体中的控件需要它执行回发时,才会生成函数 __doPostBack
。这包括 LinkButton 等控件和 AutoPostBack
设置为 true
的其他控件。事实上,只有 Button 和 ImageButton 控件可以在没有 __doPostBack
的情况下执行回发(参见 this article)。例如,我们可以在 HTML 输出中看到 LinkButton 是这样呈现的:
<a id="lnk" href="javascript:__doPostBack('lnk','')">My link</a>
解决方案 2: 下面的方法在不使用 __doPostBack. 的情况下实现了同样的效果
在本例中,您可以为 DropDownList 设置 AutoPostBack="true"
:
<asp:DropDownList AutoPostBack="true" onchange="if (!confirmPostBack(this)) return false;" ... >
当您想阻止回发时,onchange
事件处理程序将 return false
。 Javascript 函数可能是这样的:
function confirmPostBack(ddl)
{
if (condition) {
...
return true;
}
else {
...
return false;
}
}
重要:onchange
事件处理程序不应该 return 任何允许回发发生的东西。您可以使用以下语法:
onchange="if (!confirmPostBack(this)) return false;"
由于问题中提到的文章中可能解释的原因,以下语法不起作用。返回 true
仍然会阻止回发。
onchange="return confirmPostBack(this);" // Does not work!