【问题标题】:How does ASP.NET know which event to fire during a postback?ASP.NET 如何知道在回发期间要触发哪个事件?
【发布时间】:2012-04-03 07:44:27
【问题描述】:

在回发期间,__EVENTTARGET 表单变量保存发出回发的name of the control。如果控件支持多个服务器端事件,ASP.NET 如何知道该控件触发哪个事件?

【问题讨论】:

  • 你是在问为什么它在做什么,或者你如何让它工作?
  • 这些都不是。如果一个控件支持多个事件,asp.net 怎么知道要触发哪个?仅在 __EVENTTARGET 中传递控件 ID 是不够的。

标签: asp.net webforms


【解决方案1】:

正如 Wiktor 所提到的,ASP.Net 中的许多控件已经为您构建了,以便您以某些方式使用;按钮单击、文本更改、所选索引更改 - 这些控件已构建用于执行某些操作,which is why they work the way they do

来自文档:

因为大多数 ASP.NET 服务器控件事件都需要往返于 服务器进行处理,它们会影响页面的性能。 因此,服务器控件提供了一组有限的事件,通常只有 点击类型的事件。一些服务器控件支持更改事件。为了 例如,CheckBox Web 服务器控件引发 CheckedChanged 事件 当用户单击该框时,在服务器代码中。一些服务器控件 支持更多抽象事件。例如,日历 Web 服务器 控件引发一个更抽象的 SelectionChanged 事件 点击事件的版本。

当然,您可以编写自己的客户端控件,但这需要更多的工作。文章Server Event Handling in 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());
     }         

  }

【讨论】:

【解决方案2】:

借助 HTTP 嗅探器(例如 Fiddler)进行调试可以提供帮助。概括地说,事件详情在__EVENTARGUMENT 表单字段中。如何解包数据是特定控件的实现细节。

例如,将TreeView 拖放到表单上,并连接其TreeNodeCollapsedTreeNodeExpandedSelectedNodeChanged 事件。您会看到展开或折叠一个节点会导致回发,其中tnode_text in __EVENTARGUMENT;而选择一个节点会导致在__EVENTARGUMENT 中返回类似snode_text 的内容。我的猜测是 t 代表“切换”,s 代表“选择”,但我还没有深入研究源代码。

(顺便说一句,只是说“切换”对于展开和折叠都足够好,因为..._ExpandState 表单变量包含所有节点展开状态的详细信息,看起来像)。

【讨论】:

    【解决方案3】:

    要处理回发 ASP.NET 服务器控件必须实现IPostBackEventHandler 接口。该接口有一个方法void RaisePostBackEvent(string eventArgument),它处理表单发布到服务器时引发的事件。

    该方法负责引发控件的服务器端事件。这里唯一的参数是eventArgument,如果需要,它用于区分事件的类型(如GridView)。

    例如Button 控件同时引发 ClickCommand 事件。 GridView 从事件参数参数中解析命令名称,并为命令触发必要的事件。

    您可以使用 .NET 反编译器(我为此使用了出色的 JetBrains dotPeek)来查看标准 ASP.NET 控件的 RaisePostBackEvent 方法的实现。

    【讨论】:

      【解决方案4】:

      我想如果控件包含 单个 值并传入表单的数据,则无需怀疑 - TextBox 可以更改DropDownList 的值可以更改等。

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

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

      【讨论】:

        【解决方案5】:

        如果您想在控件中处理回发事件,您将实现IPostBackEventHandler 接口。框架将调用接受 eventArgument 的 IPostBackEventHandler.RaisePostBackEvent 方法。根据 event 参数,您可以引发各种其他自定义事件。

        框架会自动调用其他控件事件,如 Init、Load 等,无论控件是否可以处理回发事件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-04-02
          • 1970-01-01
          • 2019-02-11
          • 1970-01-01
          • 2011-12-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多