ASP.NET如何在回发期间知道要触发哪个事件?

3

在后台回发期间,__EVENTTARGET表单变量保存了发起回发的控件名称。如果该控件支持多个服务器端事件,ASP.NET如何知道为该控件触发哪个事件?


你是在问为什么它会做这些事情,还是想知道怎样让它工作? - brizz
如果一个控件支持多个事件,那么asp.net如何知道要触发哪个事件?仅仅通过在__EVENTTARGET中传递控件ID是不够的。 - Tony_Henrich
5个回答

5
正如Wiktor所提到的,ASP.Net中的许多控件已经为您构建好了,以便以特定方式使用;按钮单击、文本更改、选定索引更改 - 这些控件已经被构建成执行特定任务,这就是为什么它们按照特定方式工作的原因
根据文档:
由于大多数ASP.NET服务器控件事件需要往返到服务器进行处理,它们可能会影响页面的性能。因此,服务器控件提供了有限的事件集,通常只有点击类型的事件。一些服务器控件支持更改事件。例如,当用户单击框时,CheckBox Web服务器控件在服务器代码中引发CheckedChanged事件。一些服务器控件支持更抽象的事件。例如,Calendar Web服务器控件引发SelectionChanged事件,它是单击事件的更抽象版本。
你当然可以编写自己的客户端控件,但这需要更多的工作。文章ASP.Net中的服务器事件处理讨论了这个问题。总之,重要的部分是实现RaisePostBackEvent
如果你想提供多个事件,那么你可以从客户端发送不同的事件参数给该方法,并触发适当的服务器端事件。这可以简单地通过一个if语句实现。一个基本的例子是有两个客户端javascript事件,每个事件可能调用:
__doPostBack(controlId, 'superclick');

__doPostBack(pageId, 'superchange');

在您的回发事件处理程序中,根据传递的参数调用所需的服务器端事件。一个简单的RaisePostBackEvent服务器端处理程序看起来会像这样:
  public void RaisePostBackEvent(string eventArgument){

     if(eventArgument == "superclick")
     {
        OnSuperClick(this, new EventArgs());
     }

     if(eventArgument == "superchange")
     {
        OnSuperChange(this, new EventArgs());
     }         

  }

RaisePostBackEvent 包含两个参数 http://msdn.microsoft.com/en-us/library/system.web.ui.page.raisepostbackevent.aspx - Pankaj
@PankajGarg 那是Page.RaisePostBackEvent。请参见答案中引用的http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackeventhandler.raisepostbackevent.aspx。或者,当回传时,您可以懒惰地查看Page.Request.Params [“__EVENTARGUMENT”]。 - dash

2
利用HTTP嗅探器(例如Fiddler)进行调试可以帮助解决问题。总体来说,事件详细信息在__EVENTARGUMENT表单字段中。如何解包这些数据是特定控件的实现细节。
例如,在表单上放置一个TreeView,并连接其TreeNodeCollapsedTreeNodeExpandedSelectedNodeChanged事件。您会发现展开或折叠节点会导致一个带有类似于tnode_text的内容在__EVENTARGUMENT中的后台提交;而选择节点会导致一个带有类似于snode_text的内容在__EVENTARGUMENT中的后台提交。我猜t代表"toggle",s代表"select",但我没有深入源代码进行确认。
(顺便说一下,只说"toggle"就足以表示展开和折叠,因为..._ExpandState表单变量保存了所有节点的展开状态详细信息,看起来是这样的。)

1
为了处理PostBack,ASP.NET服务器控件必须实现IPostBackEventHandler接口。该接口有一个单一的方法void RaisePostBackEvent(string eventArgument),用于处理当表单提交到服务器时引发的事件。
该方法负责引发控件的服务器端事件。这里唯一的参数是eventArgument,如果需要(如GridView),它用于区分事件类型。
例如,Button控件会引发ClickCommand事件。GridView从事件参数中解析出命令名称,并为命令触发必要的事件。
您可以使用.NET反编译器(我使用了优秀的JetBrains dotPeek)来查看标准ASP.NET控件的RaisePostBackEvent方法的实现。

0

我猜在控件只保存一个值的情况下,传递表单数据时不需要任何疑虑——TextBox可以被更改,DropDownList的值也可以被更改。

事实上,这些控件通常只有一个事件从客户端触发,其他事件都是为服务器端管道服务的(DataBindingDataBoundInitLoad等)。

另一方面,任何复合控件都可以使用__EVENTARGUMENTS向服务器提供附加参数,以便确定和分派实际事件。


0
如果您想在控件中处理后台回传事件,您需要实现 IPostBackEventHandler 接口。框架会调用 IPostBackEventHandler.RaisePostBackEvent 方法,该方法接受 eventArgument。根据事件参数,您可以触发其他各种自定义事件。
框架会自动调用其他控件事件,如 Init、Load 等,无论控件是否能处理后台回传事件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接