2009-03-01 33 views
1

我一直在做C#多年,但ASP.NET不那么久,这让我难住。为什么在Javascript中附加事件处理程序会阻止我的服务器端事件触发?

在我的故障诊断示例中,我在ASP.NET页面中有一个下拉列表,它有四个项目,我有一个在selectedindexchanged上触发的serverside事件,它在这种情况下都很好。但是,如果(因为我在我的演变代码中)为“onchange”事件设置了Javascript处理程序(它启动警报),警报正常工作,但服务器端事件不再触发...我确定我错过了一些明显的东西。

重要提示:Autopostback设置为true的下拉列表控制,视图状态已启用,JavaScript的事件处理程序返回true

有人吗?

这不是我必须手动连线__doPostBack是吗?

任何帮助非常感谢。

编辑

确定这里是代码的第一代码隐藏

using System; 
using System.Data; 
using System.Configuration; 
using System.Collections; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.HtmlControls; 
using System.Text; 

namespace TestEvents 
{ 
public partial class _Default : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 

    } 

    protected override void OnPreRender(EventArgs e) 
    { 

     ClientScriptManager csm = Page.ClientScript; 
     if (!csm.IsClientScriptBlockRegistered("NotesChangeScript")) 
     { 
      StringBuilder sb = new StringBuilder(); 
      sb.Append("\r\n <script type=\"text/javascript\"> \r\n"); 
      sb.Append(" //<![CDATA[ \r\n"); 
      sb.Append(" var changesCount = 0; \r\n"); 

      sb.Append(" function selection_handler()\r\n"); 
      sb.Append("{ \r\n"); 
      sb.Append(" changesCount += 1;\r\n"); 
      sb.Append(" alert('i changed on the client!'); \r\n"); 
      sb.Append(" return true; \r\n"); 
      sb.Append(" } \r\n"); 

      sb.Append(" function SetUpNotesHandler() \r\n"); 
      sb.Append("{ \r\n"); 
      sb.Append("   var ctrls = document.getElementsByTagName(\"SELECT\");\r\n"); 
      sb.Append("   for(i=0;i<ctrls.length;i++)\r\n"); 
      sb.Append("     {\r\n"); 
      sb.Append("      ctrls[i].onchange = selection_handler; \r\n"); 
      sb.Append("     }\r\n"); 
      sb.Append("}\r\n"); 


      sb.Append(" //]]> \r\n"); 
      sb.Append("</script>"); 

      csm.RegisterClientScriptBlock(this.GetType(), "NotesChangeScript", sb.ToString(), false); 

      StringBuilder initScript = new StringBuilder(); 
      initScript.Append("<script type=\"text/javascript\" >\r\n"); 
      initScript.Append(" //<![CDATA[\r\n"); 
      initScript.Append(" SetUpNotesHandler(); \r\n"); 
      initScript.Append(" //]]> \r\n"); 
      initScript.Append("</script> \r\n"); 
      csm.RegisterStartupScript(this.GetType(), "StartUpKey", initScript.ToString(),false); 
      base.OnPreRender(e); 
     } 

    } 
    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     Response.Write("i hit the server event"); 
    } 
} 

}

这里是页面

<%@ Page Language="C#" AutoEventWireup="true"  CodeBehind="Default.aspx.cs" Inherits="TestEvents._Default" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" > 
<head runat="server"> 
<title>problem</title> 
</head> 
<body> 
<form id="form1" runat="server"> 
<div> 
    <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"> 
     <asp:ListItem>Numero Uno</asp:ListItem> 
     <asp:ListItem>Numer Deux</asp:ListItem> 
     <asp:ListItem>Number Three</asp:ListItem> 
     <asp:ListItem>Nomina Quatros</asp:ListItem> 
    </asp:DropDownList> 
    <asp:HiddenField ID="hdnFieldChange" runat="server" /> 
</div> 
</form> 
</body> 
</html> 

回答

0

好的,首先,要感谢ScarletGarden为了清楚问题所在,我承担了尽可能多的工作,但是当有人确认您的怀疑时,我的承诺非常高。

其次,对不住那些谁认为这是某种形式的n00b问题,找到这个问题的整个前提愚蠢的,我真的无法找到澄清这一特定问题的任何物品......

第三,我现在有计算出了如何在Javascript中完成这项工作(虽然猩红色花园解决方案在几乎所有情况下都简单得多),尽管如果你有多个处理程序并需要它们以某种方式进行触发,attributes.add方法(如scarletGarden建议的方法)可能会受到影响序列。

在反射器中有一点挖掘之后,Attributes.Add通过用分号分隔它们的分号添加事件引用,所以这很明显起作用,因为它保留已经声明的任何处理程序,而用分号分隔您添加的处理程序。

在JavaScript中,这种类型的链接(一种多播)要求使用DOM级别2功能(JavaScript圣经对识别此功能非常有用),Mozilla和IE有不同的实现方式并不奇怪同样的事情,所以,为了增加一个js处理程序,并保留事件代码隐藏处理,在我上面的例子,该行表示,通过更换

ctrls[i].onchange = selection_handler; \r\n 

需要以下(人得到宝贵的关于这之前例如我对此有很大的警告,进一步下降)

sb.Append("     if (ctrls[i].addEventListener) ctrls[i].addEventListener(\"change\",selection_handler,false);"); 
sb.Append("     else if (ctrls[i].attachEvent) ctrls[i].attachEvent(\"on\" + \"change\", selection_handler, false);"); 
sb.Append("     else return false;"); 

的attachEvent在IE中的addEventListener在Firefox中工作(注意,事件名称不同,Mozilla的宁愿放弃“开”

这样添加事件工作在LIFO(后进先出)的方式,也有许多替代方案使用更精细的JavaScript以这种方式对事件进行排序,覆盖在一个优秀的,如果稍微混乱的线程(因为它启动的方式)http://codingforums.com/showthread.php?t=154673

我希望这个东西能启发别人,就像我一样,这是线程我正在寻找当我第一次遇到问题,现在我觉得有点愚蠢,但嘿嘿

0

标记这听起来我像你有两个同步异步postbac ks同时发生,默认情况下,最近的回发优先,您必须更改。您可以强制回发到每个终点允许下一个与脚本继续之前发现here

或者你可以处理您onselectedindex改变事件的警报服务器端,喜欢的东西:

ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), 
Guid.NewGuid().ToString(),"alert('Person was added 
successfully.');location.replace('people.aspx');",true); 
0

如果你的Javascript事件处理程序取消事件冒泡,由asp.net插入的调用服务器端代码的事件处理程序将不会运行。

我不熟悉asp.net auto-inserted-things,并且你没有发布你的事件处理程序的代码,所以我不能告诉你如何解决这个问题。我的建议是使用jQuery来附加你的事件处理程序,而不是以更详细的方式返回false或取消事件冒泡。

0

将您的脚本onchange事件这样的:

DropDownList1.Attributes["onchange"] += "alert('alert');"; 

不使用回归真实;警报后。

编辑:

问题是在这里,您可以通过分配在它的脚本禁用回发的脚本,所以回发的脚本不能正常工作,因为它不存在了:

sb.Append("      ctrls[i].onchange += selection_handler; \r\n"); 

希望这有助于!

+0

你能解释为什么事情租在我的情况下工作? – Matt 2009-03-01 00:45:08

相关问题