Gebeurtenissen afhandelen en aanroepen
Gebeurtenissen in .NET zijn gebaseerd op het gemachtigde model. Het gemachtigde model volgt het ontwerppatroon voor waarnemers, waarmee een abonnee zich kan registreren bij en meldingen van een provider kan ontvangen. Een afzender van een gebeurtenis pusht een melding wanneer een gebeurtenis plaatsvindt. Een gebeurtenisontvanger definieert het antwoord. In dit artikel worden de belangrijkste onderdelen van het gemachtigde model beschreven, hoe u gebeurtenissen in toepassingen kunt gebruiken en hoe u gebeurtenissen in uw code implementeert.
Gebeurtenissen genereren met een afzender van een gebeurtenis
Een gebeurtenis is een bericht dat door een object wordt verzonden om het optreden van een actie aan te geven. De actie kan gebruikersinteractie zijn, zoals een knop drukken, of het kan het gevolg zijn van andere programmalogica, zoals een wijziging van de eigenschapswaarde. Het object dat de gebeurtenis genereert, wordt de afzender van de gebeurtenisgenoemd. De afzender van de gebeurtenis weet niet welk object of welke methode de gegenereerde gebeurtenissen ontvangt (verwerkt). De gebeurtenis is meestal onderdeel van de gebeurtenisverzender. De Click-gebeurtenis is bijvoorbeeld lid van de klasse Button en de PropertyChanged gebeurtenis is lid van de klasse waarmee de INotifyPropertyChanged-interface wordt geïmplementeerd.
Als u een gebeurtenis wilt definiëren, gebruikt u de C#-gebeurtenis of het trefwoord Visual Basic Event in de handtekening van uw gebeurtenisklasse en geeft u het type gemachtigde voor de gebeurtenis op. Gemachtigden worden beschreven in de volgende sectie.
Als u een gebeurtenis wilt genereren, voegt u meestal een methode toe die is gemarkeerd als protected
en virtual
(in C#) of Protected
en Overridable
(in Visual Basic). De naamconventie voor de methode wordt On<EventName>
, zoals OnDataReceived
. De methode moet één parameter gebruiken waarmee een gebeurtenisgegevensobject wordt opgegeven. Dit is een object van het type EventArgs of een afgeleid type. U geeft deze methode op om afgeleide klassen in staat te stellen de logica voor het genereren van de gebeurtenis te overschrijven. Een afgeleide klasse moet altijd de On<EventName>
methode van de basisklasse aanroepen om ervoor te zorgen dat geregistreerde gemachtigden de gebeurtenis ontvangen.
In het volgende voorbeeld ziet u hoe u een gebeurtenis met de naam ThresholdReached
declareert. De gebeurtenis is gekoppeld aan de EventHandler afgevaardigde en wordt aangeroepen in een methode met de naam OnThresholdReached
.
class Counter
{
public event EventHandler ThresholdReached;
protected virtual void OnThresholdReached(EventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// provide remaining implementation for the class
}
Public Class Counter
Public Event ThresholdReached As EventHandler
Protected Overridable Sub OnThresholdReached(e As EventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' provide remaining implementation for the class
End Class
Gedelegeerde handtekeningen declareren voor gebeurtenis-handlers
Een gemachtigde is een type dat een verwijzing naar een methode bevat. Een gemachtigde wordt gedeclareerd met een handtekening met het retourtype en de parameters voor de methoden waarnaar wordt verwezen. Het kan alleen verwijzingen bevatten naar methoden die overeenkomen met de handtekening. Een gemachtigde is gelijk aan een typeveilige functieaanwijzer of een callback. Een gedelegeerdedeclaratie is voldoende om een gemachtigdeklasse te definiëren.
Delegates hebben veel toepassingen in .NET. In de context van gebeurtenissen is een gemachtigde een intermediair (of pointer-achtig mechanisme) tussen de gebeurtenisbron en de code die de gebeurtenis verwerkt. U koppelt een gemachtigde aan een gebeurtenis door het type gemachtigde in de gebeurtenisdeclaratie op te neem, zoals wordt weergegeven in het voorbeeld in de vorige sectie. Zie de Delegate-klasse voor meer informatie over gemachtigden.
.NET biedt de EventHandler en EventHandler<TEventArgs> gemachtigden ter ondersteuning van de meeste gebeurtenisscenario's. Gebruik de EventHandler gedelegeerde voor alle gebeurtenissen die geen gebeurtenisgegevens bevatten. Gebruik de EventHandler<TEventArgs> gedelegeerde voor gebeurtenissen die gegevens over de gebeurtenis bevatten. Deze gemachtigden hebben geen retourtypewaarde en hebben twee parameters (een object voor de bron van de gebeurtenis en een object voor gebeurtenisgegevens).
Gemachtigden zijn multicast- klasseobjecten. Dit betekent dat ze verwijzingen naar meer dan één methode voor gebeurtenisafhandeling kunnen bevatten. Zie de referentiepagina Delegate voor meer informatie. Gedelegeerden bieden flexibiliteit en fijnmazige controle bij het afhandelen van gebeurtenissen. Een gemachtigde fungeert als een gebeurtenis-dispatcher voor de klasse die de gebeurtenis genereert door een lijst met geregistreerde gebeurtenis-handlers voor de gebeurtenis te onderhouden.
Gebruik de EventHandler en EventHandler<TEventArgs> gedelegeerdentypen om de benodigde gemachtigde te definiëren. Je markeert een gemachtigde met het delegate
type in [C#](../../csharp/language-reference/builtin-types/reference-types.md#the-delegate-type) of het Delegate
type in Visual Basic in de declaratie. In het volgende voorbeeld ziet u hoe u een gemachtigde met de naam ThresholdReachedEventHandler
declareert:
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
Public Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)
Werken met gebeurtenisgegevensklassen
Gegevens die aan een gebeurtenis zijn gekoppeld, kunnen worden opgegeven via een gebeurtenisgegevensklasse. .NET biedt veel gebeurtenisgegevensklassen die u in uw toepassingen kunt gebruiken. De SerialDataReceivedEventArgs-klasse is bijvoorbeeld de gebeurtenisgegevensklasse voor de SerialPort.DataReceived gebeurtenis. .NET volgt een naamgevingspatroon waarbij alle gebeurtenisgegevensklassen eindigen met het achtervoegsel EventArgs
. U bepaalt welke gebeurtenisgegevensklasse aan een gebeurtenis is gekoppeld door de gemachtigde voor de gebeurtenis te bekijken. Bijvoorbeeld, de gedelegeerde SerialDataReceivedEventHandler neemt de klasse SerialDataReceivedEventArgs als parameter op.
De EventArgs-klasse is doorgaans het basistype voor gebeurtenisgegevensklassen. U gebruikt deze klasse ook als aan een gebeurtenis geen gegevens zijn gekoppeld. Wanneer u een gebeurtenis maakt die abonnees op de hoogte stelt dat er iets is gebeurd zonder extra gegevens, neemt u de EventArgs klasse op als de tweede parameter in de gemachtigde. U kunt de EventArgs.Empty-waarde doorgeven wanneer er geen gegevens worden opgegeven. De EventHandler delegate neemt de EventArgs klasse op als parameter.
U kunt een klasse maken die is afgeleid van de EventArgs-klasse om noodzakelijke leden te bieden die gegevens die met de gebeurtenis verband houden doorgeven. Normaal gesproken moet u hetzelfde naamgevingspatroon gebruiken als .NET en de naam van de gebeurtenisgegevensklasse beëindigen met het achtervoegsel EventArgs
.
In het volgende voorbeeld ziet u een gebeurtenisgegevensklasse met de naam ThresholdReachedEventArgs
die eigenschappen bevat die specifiek zijn voor de gegenereerde gebeurtenis:
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
Public Class ThresholdReachedEventArgs
Inherits EventArgs
Public Property Threshold As Integer
Public Property TimeReached As DateTime
End Class
Reageren op gebeurtenissen met handlers
Als u wilt reageren op een gebeurtenis, definieert u een gebeurtenis-handlermethode in de gebeurtenisontvanger. Deze methode moet overeenkomen met de ondertekening van de delegate voor het event dat u afhandelt. In de gebeurtenis-handler voert u de acties uit die vereist zijn wanneer de gebeurtenis wordt gegenereerd, zoals het verzamelen van gebruikersinvoer nadat de gebruiker op een knop drukt. Als u meldingen wilt ontvangen wanneer de gebeurtenis plaatsvindt, moet uw gebeurtenis-handlermethode zich abonneren op de gebeurtenis.
In het volgende voorbeeld ziet u een gebeurtenishandlermethode met de naam c_ThresholdReached
die overeenkomt met de handtekening voor de EventHandler gemachtigde. De methode abonneert zich op de gebeurtenis ThresholdReached
:
class ProgramTwo
{
static void Main()
{
var c = new Counter();
c.ThresholdReached += c_ThresholdReached;
// provide remaining implementation for the class
}
static void c_ThresholdReached(object sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
}
}
Module Module1
Sub Main()
Dim c As New Counter()
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' provide remaining implementation for the class
End Sub
Sub c_ThresholdReached(sender As Object, e As EventArgs)
Console.WriteLine("The threshold was reached.")
End Sub
End Module
Statische en dynamische gebeurtenis-handlers gebruiken
Met .NET kunnen abonnees zich registreren voor gebeurtenismeldingen, statisch of dynamisch. Statische gebeurtenis-handlers zijn van kracht voor de hele levensduur van de klasse waarvan ze gebeurtenissen verwerken. Dynamische gebeurtenis-handlers worden expliciet geactiveerd en gedeactiveerd tijdens het uitvoeren van het programma, meestal in reactie op bepaalde voorwaardelijke programmalogica. U kunt dynamische handlers gebruiken wanneer gebeurtenismeldingen alleen onder bepaalde voorwaarden nodig zijn of wanneer runtimevoorwaarden bepalen welke specifieke handler moet worden aangeroepen. In het voorbeeld in de vorige sectie ziet u hoe u dynamisch een gebeurtenis-handler toevoegt. Zie Events (in Visual Basic) en Events (in C#) voor meer informatie.
Meerdere gebeurtenissen genereren
Als uw klasse meerdere gebeurtenissen afvuurt, genereert de compiler één veld per event-delegate-instantie. Als het aantal gebeurtenissen groot is, zijn de opslagkosten van één veld per gemachtigde mogelijk niet acceptabel. Voor deze scenario's biedt .NET gebeurteniseigenschappen die u kunt gebruiken met een andere gegevensstructuur van uw keuze om gedelegeerden van gebeurtenissen op te slaan.
Gebeurteniseigenschappen bestaan uit gebeurtenisdeclaraties, vergezeld van gebeurtenistoegangsmethoden. Gebeurtenistoegangsors zijn methoden die u definieert voor het toevoegen of verwijderen van gedelegeerde instanties van de opslaggegevensstructuur.
Notitie
De gebeurteniseigenschappen zijn langzamer dan de gebeurtenisvelden, omdat elke event-delegate moet worden opgehaald voordat hij kan worden aangeroepen.
De afweging is tussen geheugen en snelheid. Als uw klasse veel gebeurtenissen definieert die niet vaak worden gegenereerd, moet u gebeurteniseigenschappen implementeren. Zie Meerdere gebeurtenissen verwerken met behulp van gebeurteniseigenschappenvoor meer informatie.
Ontdek verwante taken
In de volgende resources worden andere taken en concepten beschreven die betrekking hebben op het werken met gebeurtenissen:
- gebeurtenissen genereren en gebruiken: voorbeelden zoeken voor het genereren en gebruiken van gebeurtenissen.
- meerdere gebeurtenissen verwerken met gebeurteniseigenschappen: Ontdek hoe u gebeurteniseigenschappen gebruikt om meerdere gebeurtenissen af te handelen.
- Bekijk het ontwerppatroon van de waarnemer: Bekijk een ontwerppatroon waarmee een abonnee zich kan registreren bij en meldingen van een provider kan ontvangen.
Specificatiereferentie bekijken
Documentatie over specificatiereferenties is beschikbaar voor de API's die ondersteuning bieden voor gebeurtenisafhandeling:
API-naam | API-type | Referentie |
---|---|---|
EventHandler | Gedelegeerde | EventHandler |
EventHandler<TEventArgs> | Gedelegeerde | EventHandler<TEventArgs> |
EventArgs | Klasse | EventArgs |
Gedelegeerde | Klasse | Delegate |