定義事件
如果您不熟悉事件的委派 (Delegate) 模型,請參閱處理和引發事件。
事件功能由下列項目提供。
儲存事件資料的類別 (例如,EventArgs、ImageClickEventArgs)。
事件委派 (例如,EventHandler、ImageClickEventHandler)。
注意 前面兩個類別通常在您的控制項外部定義。下列兩個成員定義於您的控制項中。
定義於您控制項中的事件成員。這將由 event 關鍵字來辨識。
您的控制項中叫用委派 (例如,OnClick、OnTextChanged) 的方法。
下列範例定義自訂控制項 MyButton
中的 Click
事件。
// If the event does not generate data, you do not have
// to define a class for the event data or define an event delegate.
// Use System.EventArgs for event data
// and System.EventHandler as the event delegate.
// MyButton uses EventHandler and EventArgs.
using System;
using System.Web.UI;
namespace CustomControls
{
public class MyButton: Control, IPostBackEventHandler
{
// Defines the Click event.
public event EventHandler Click;
// OnClick dispatches the event to delegates that
// are registered with the Click event.
// Controls that derive from MyButton can handle the
// Click event by overriding OnClick
// instead of attaching a delegate. The event data
// is passed as an argument to this method.
protected virtual void OnClick(EventArgs e)
{
if (Click != null)
{
Click(this, e);
}
}
// Method of IPostBackEventHandler that raises change events.
public void RaisePostBackEvent(string eventArgument)
{
OnClick(EventArgs.Empty);
}
protected override void Render(HtmlTextWriter output)
{
output.Write("<INPUT TYPE = submit name = " + this.UniqueID +
" Value = 'Click Me' />");
}
}
}
[Visual Basic]
' If the event does not generate data, you do not have
' to define a class for the event data or define an event delegate.
' Use System.EventArgs for event data
' and System.EventHandler as the event delegate.
' MyButton uses EventHandler and EventArgs.
Option Explicit
Option Strict
Imports System
Imports System.Web.UI
Namespace CustomControls
Public Class MyButton
Inherits Control
Implements IPostBackEventHandler
' Defines the Click event.
Public Event Click As EventHandler
' OnClick dispatches the event to delegates that
' are registered with the Click event.
' Controls that derive from MyButton can handle the
' Click event by overriding OnClick
' instead of attaching a delegate. The event data
' is passed as an argument to this method.
Protected Overridable Sub OnClick(e As EventArgs)
RaiseEvent Click(Me, e)
End Sub
' Method of IPostBackEventHandler that raises change events.
Public Sub RaisePostBackEvent(eventArgument As String) Implements IPostBackEventHandler.RaisePostBackEvent
OnClick(EventArgs.Empty)
End Sub 'RaisePostBackEvent
Protected Overrides Sub Render(output As HtmlTextWriter)
output.Write(("<INPUT TYPE = submit name = " & Me.UniqueID & " Value = 'Click Me' />"))
End Sub
End Class
End Namespace
除了定義事件外,控制項開發人員也必需決定如何引發事件 (要叫用 OnEventName 方法的地方)。例如,MyButton
從其 RaisePostBackEvent 方法 (為 IPostBackEventHandler 合約的一部分) 引發 Click
事件。如需這個範例的詳細資訊,請參閱擷取回傳事件。
最佳化事件實作
前面說明的事件實作就效能而言並非是最佳化的。它按每個委派執行個體產生一個欄位,這在有許多事件定義於控制項時會增加儲存成本。基底類別 System.Web.UI.Control 提供更有效率的資料結構 (透過其 Events 屬性) 來儲存和擷取事件委派。Events 屬性的型別為 EventHandlerList,這是針對事件委派的有效率儲存和擷取而設計的資料結構。下列範例示範使用 Events 屬性的事件實作。這個 C# 範例與稍早定義於這個主題的 MyButton
範例只在其 Click
事件的實作 (Implementation) 中有差異。實作這個事件的程式碼以粗體字型強調。
注意 這個版本中的 Visual Basic .NET 並不支援事件屬性。
using System;
using System.Web.UI;
namespace CustomControls
{
public class OptimizedEventButton: Control, IPostBackEventHandler
{
// Defines a key for storing the delegate for the Click event
// in the Events list.
private static readonly object ClickEvent = new object();
// Defines the Click event using the event property syntax.
// The Events property stores all the event delegates of
// a control as name/value pairs.
public event EventHandler Click
{
// When a user attaches an event handler to the Click event
// (Click += myHandler;), the Add method
// adds the handler to the
// delegate for the Click event (keyed by ClickEvent
// in the Events list).
add { Events.AddHandler(ClickEvent, value); }
// When a user removes an event handler from the Click event
// (Click -= myHandler;), the Remove method
// removes the handler from the
// delegate for the Click event (keyed by ClickEvent
// in the Events list).
remove { Events.RemoveHandler(ClickEvent, value); }
}
// Invokes delegates registered with the Click event.
//
protected virtual void OnClick(EventArgs e)
{
// Retrieves the event delegate for the Click event
// from the Events property (which stores
// the control's event delegates). You must
// cast the retrieved delegate to the type of your
// event delegate.
EventHandler clickEventDelegate = (EventHandler)Events[ClickEvent]; if (clickEventDelegate != null) { clickEventDelegate(this, e); }
}
// Method of IPostBackEventHandler that raises change events.
//
public void RaisePostBackEvent(string eventArgument)
{
OnClick(new EventArgs());
}
protected override void Render(HtmlTextWriter output)
{
output.Write("<INPUT TYPE = submit name = " + this.UniqueID +
" Value = 'Click Me' />");
}
}
}
注意 為簡單起見,文件中的一些其他範例使用事件欄位來定義事件。然而在您的控制項中,您應該使用這裡討論的最佳化實作。
請參閱
處理和引發事件 | 反昇事件 | 處理回傳資料 | 擷取回傳事件 | 產生回傳的用戶端指令碼