使用事件
若要在應用程式中使用事件,您必須提供可執行程式邏輯以回應事件並且向事件來源 (Event Source) 註冊事件處理常式 (一種事件處理方法) 的事件處理常式。 這個處理序稱為事件連接 (Event Wiring)。 Windows Form 和 Web Form 的視覺化設計工具會提供可簡化或隱藏事件連接詳細資料的快速應用程式開發 (Rapid Application Development,RAD) 工具。
本主題說明處理事件的一般模式。 如需 .NET Framework 中事件模型的概觀,請參閱事件和委派。 如需 Windows Form 內事件模型的詳細資訊,請參閱 HOW TO:使用 Windows Form 應用程式中的事件。 如需 Web Form 內事件模型的詳細資訊,請參閱 HOW TO:使用 Web Form 應用程式中的事件。
事件模式
Windows Form 和 Web Form 中事件連接的詳細資料會因 RAD 工具所提供不同層級的支援而有所差異。 然而,兩種案例都會遵循相同的事件模式,其特性如下:
- 引發名為 EventName 之事件的類別具有下列成員:
Public Event EventName As EventNameEventHandler
public event EventNameEventHandler EventName;
public:
event EventNameEventHandler^ EventName;
- EventName 事件的事件委派為 EventNameEventHandler,具有下列簽章:
Public Delegate Sub EventNameEventHandler(sender As Object, e As EventNameEventArgs)
public delegate void EventNameEventHandler(object sender, EventNameEventArgs e);
delegate void EventNameEventHandler(Object^ sender, EventNameEventArgs^ e);
若要使用 EventName 事件,您的事件處理常式必須具有與事件委派同樣的簽章:
Sub EventHandler(sender As Object, e As EventNameEventArgs)
End Sub
void EventHandler(object sender, EventNameEventArgs e) {}
void EventHandler(Object^ sender, EventNameEventArgs^ e) {}
注意事項 |
---|
.NET Framework 中的事件委派名稱為 EventNameEventHandler,而文件中的事件處理常式一詞,則是指事件處理方法。這種命名配置所依據的邏輯是,EventNameEventHandler 委派會指向實際處理事件的事件處理常式 (方法)。 |
當事件沒有任何關聯的資料時,引發此事件的類別會使用 System.EventHandler 做為委派,並使用 System.EventArgs 做為事件資料。 具有關聯資料的事件會使用衍生自事件資料型別之 EventArgs 的類別,和對應的事件委派型別。 舉例來說,如果您想要處理某個 Windows Form 應用程式中的 MouseUp 事件,那麼事件資料類別便是 MouseEventArgs,而事件委派則是 MouseEventHandler。 請注意,由於幾個滑鼠事件是使用通用的事件資料類別和通用的事件委派,所以命名配置並未完全符合上面所述的慣例。 如果是滑鼠事件,事件處理常式必須具有下列簽章:
Sub Mouse_Moved(sender As Object, e As MouseEventArgs)
End Sub
void Mouse_Moved(object sender, MouseEventArgs e){}
void Mouse_Moved(Object^ sender, MouseEventArgs^ e){}
傳送者和事件引數參數會提供關於滑鼠事件的其他詳細資料給事件處理常式。 傳送者物件表示引發此事件的原因。 MouseEventArgs 參數會提供引發此事件之滑鼠移動的詳細資料。 許多事件來源都會提供事件的額外資料,許多事件處理常式也會使用事件特定的資料來處理事件。 如需說明使用事件特定資料引發和處理事件的範例,請參閱 HOW TO:引發和使用事件。
注意事項 |
---|
事件也會在使用者介面 (UI) 的內容之外引發,事實上,.NET Framework 包括許多可以引發事件的非 UI 類別。不過,所有遵循該模式的事件都已在此討論。 |
如需從類別引發事件的詳細資訊,請參閱引發事件。
靜態和動態事件
.NET Framework 允許訂閱者靜態或動態註冊事件通知。 靜態事件處理常式會在處理其事件之類別的整個週期持續作用中。 這是處理事件最常見的方法。 動態事件處理常式則會在程式執行期間明確地啟用和停用,以回應某些條件式程式邏輯。 例如,如果只有在某些情況下才需要事件通知,或者應用程式提供多個事件處理常式,並且執行階段狀況會決定適用的事件處理常式,則可以使用動態事件處理常式。
EventInfo.AddEventHandler 方法會加入動態事件處理常式,而 EventInfo.RemoveEventHandler 方法則會停用它們。 不同的程式語言也各自有動態處理事件的功能。 下列範例會定義 TemperatureMonitor 類別,只要溫度達到預先定義的臨界值,就會引發 TemperatureTheshold 事件。 然後,在程式執行期間,訂閱此事件的事件處理常式隨即啟動和停用。
public class TemperatureEventArgs : Inherits EventArgs
Private oldTemp As Decimal
Private newTemp As Decimal
Public ReadOnly Property OldTemperature As Decimal
Get
Return Me.oldTemp
End Get
End Property
Public ReadOnly Property NewTemperature As Decimal
Get
Return Me.newTemp
End Get
End Property
Public Sub New(oldTemp As Decimal, newTemp As Decimal)
Me.oldTemp = oldTemp
Me.newTemp = newTemp
End Sub
End Class
Public Delegate Sub TemperatureEventHandler(sender As Object, _
ev As TemperatureEventArgs)
Public Class TemperatureMonitor
Private currentTemperature As Decimal
Private threshholdTemperature As Decimal
Public Event TemperatureThreshold As TemperatureEventHandler
Public Sub New(threshHold As Decimal)
Me.threshholdTemperature = threshHold
End Sub
Public Sub SetTemperature(newTemperature As Decimal)
If (Me.currentTemperature > threshholdTemperature And _
newTemperature <= Me.threshholdTemperature) Or _
(Me.CurrentTemperature < Me.threshholdTemperature And _
newTemperature >= Me.threshholdTemperature) Then
OnRaiseTemperatureEvent(newTemperature)
End If
Me.currentTemperature = newTemperature
End Sub
Public Function GetTemperature() As Decimal
Return Me.currentTemperature
End Function
Protected Overridable Sub OnRaiseTemperatureEvent(newTemperature As Decimal)
RaiseEvent TemperatureThreshold(Me, New TemperatureEventArgs(Me.currentTemperature, _
newTemperature))
End Sub
End Class
Public Module Example
Public Sub Main()
Dim tempMon As New TemperatureMonitor(32d)
tempMon.SetTemperature(33)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
tempMon.SetTemperature(32)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
' Add event handler dynamically using Visual Basic syntax.
AddHandler tempMon.TemperatureThreshold, AddressOf TempMonitor
tempMon.SetTemperature(33)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
tempMon.SetTemperature(34)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
tempMon.SetTemperature(32)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
' Remove event handler dynamically using Visual Basic syntax.
RemoveHandler tempMon.TemperatureThreshold, AddressOf TempMonitor
tempMon.SetTemperature(31)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
tempMon.SetTemperature(35)
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
tempMon.GetTemperature())
End Sub
Private Sub TempMonitor(sender As Object, e As TemperatureEventArgs)
Console.WriteLine(" ***Warning: Temperature is changing from {0} to {1}.", _
e.OldTemperature, e.NewTemperature)
End Sub
End Module
' The example displays the following output:
' Current temperature is 33 degrees Fahrenheit.
' Current temperature is 32 degrees Fahrenheit.
' Current temperature is 33 degrees Fahrenheit.
' Current temperature is 34 degrees Fahrenheit.
' ***Warning: Temperature is changing from 34 to 32.
' Current temperature is 32 degrees Fahrenheit.
' Current temperature is 31 degrees Fahrenheit.
' Current temperature is 35 degrees Fahrenheit.
using System;
public class TemperatureEventArgs : EventArgs
{
private decimal oldTemp;
private decimal newTemp;
public decimal OldTemperature
{
get { return this.oldTemp; }
}
public decimal NewTemperature
{
get { return this.newTemp; }
}
public TemperatureEventArgs(decimal oldTemp, decimal newTemp)
{
this.oldTemp = oldTemp;
this.newTemp = newTemp;
}
}
public delegate void TemperatureEventHandler(object sender, TemperatureEventArgs ev);
public class TemperatureMonitor
{
private decimal currentTemperature;
private decimal threshholdTemperature;
public event TemperatureEventHandler TemperatureThreshold;
public TemperatureMonitor(decimal threshhold)
{
this.threshholdTemperature = threshhold;
}
public void SetTemperature(decimal newTemperature)
{
if ( (this.currentTemperature > this.threshholdTemperature &&
newTemperature <= this.threshholdTemperature) ||
(this.currentTemperature < this.threshholdTemperature &&
newTemperature >= this.threshholdTemperature) )
OnRaiseTemperatureEvent(newTemperature);
this.currentTemperature = newTemperature;
}
public decimal GetTemperature()
{
return this.currentTemperature;
}
protected virtual void OnRaiseTemperatureEvent(decimal newTemperature)
{
// Raise the event if it has subscribers.
if (TemperatureThreshold != null)
TemperatureThreshold(this, new TemperatureEventArgs(this.currentTemperature,
newTemperature));
}
}
public class Example
{
public static void Main()
{
Example ex = new Example();
ex.MonitorTemperatures();
}
public void MonitorTemperatures()
{
TemperatureMonitor tempMon = new TemperatureMonitor(32);
tempMon.SetTemperature(33);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
tempMon.SetTemperature(32);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
// Add event handler dynamically using C# syntax.
tempMon.TemperatureThreshold += this.TempMonitor;
tempMon.SetTemperature(33);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
tempMon.SetTemperature(34);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
tempMon.SetTemperature(32);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
// Remove event handler dynamically using C# syntax.
tempMon.TemperatureThreshold -= this.TempMonitor;
tempMon.SetTemperature(31);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
tempMon.SetTemperature(35);
Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
tempMon.GetTemperature());
}
private void TempMonitor(object sender, TemperatureEventArgs e)
{
Console.WriteLine(" ***Warning: Temperature is changing from {0} to {1}.",
e.OldTemperature, e.NewTemperature);
}
}
// The example displays the following output:
// Current temperature is 33 degrees Fahrenheit.
// Current temperature is 32 degrees Fahrenheit.
// Current temperature is 33 degrees Fahrenheit.
// Current temperature is 34 degrees Fahrenheit.
// ***Warning: Temperature is changing from 34 to 32.
// Current temperature is 32 degrees Fahrenheit.
// Current temperature is 31 degrees Fahrenheit.
// Current temperature is 35 degrees Fahrenheit.
請參閱
工作
HOW TO:使用 Windows Form 應用程式中的事件