Sdílet prostřednictvím


Zpracování událostí

Chcete-li v aplikaci zpracovávat události, musíte poskytnout obslužnou rutinu události (metoda zpracování události), která provede programovou logiku jakožto odpověď na událost a registrovat danou obslužnou rutinu události ke zdroji události. Tento proces se nazývá propojení událostí. Vizuální návrháři pro model Windows Forms a Web Forms poskytují nástroje pro rychlý vývoj aplikací (RAD), které zjednodušují nebo skrývají podrobnosti o propojování událostí.

Toto téma popisuje obecný vzor zpracování událostí. Přehled o modelu událostí v rozhraní .NET Framework naleznete v tématu Události a delegáti. Další informace o modelu událostí v modelu Windows Forms naleznete v tématu Postupy: Zacházení s událostmi v aplikacích modelu Windows Forms. Další informace o modelu událostí v modelu Web Forms naleznete v tématu Postupy: Zacházení s událostmi v aplikacích s webovými formuláři.

Vzor událostí

Podrobnosti o propojování událostí se liší v modelu Windows Forms a Web Forms z důvodu různých úrovní podpory poskytované různými nástroji pro rychlý vývoj aplikací (RAD). Oba postupy se však drží stejného vzoru událostí, který má následující charakteristiky:

  • Třída, která vyvolává událost s názvem EventName má následující člen:
Public Event EventName As EventNameEventHandler
public event EventNameEventHandler EventName;
public:
    event EventNameEventHandler^ EventName;
  • Delegát události pro událost EventName je EventNameEventHandler s následující signaturou:
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);

Chcete-li zpracovat událost EventName, vaše obslužná rutina události musí mít stejnou signaturu jako delegát události:

Sub EventHandler(sender As Object, e As EventNameEventArgs)
End Sub
void EventHandler(object sender, EventNameEventArgs e) {}
void EventHandler(Object^ sender, EventNameEventArgs^ e) {}
PoznámkaPoznámka

Delegát události v rozhraní .NET Framework je pojmenován EventNameEventHandler, termín obslužné rutiny události přitom v dokumentaci odkazuje na metodu zpracovávající událost.Logika za schématem pojmenování je taková, že delegát EventNameEventHandler odkazuje na obslužnou rutinu události (metodu), která danou událost skutečně zpracovává.

Pokud událost nemá žádná přidružená data, třída vyvolávající událost používá jako delegáta System.EventHandler a System.EventArgs pro data události. Události s přidruženými daty využívají tříd, které dědí z EventArgs pro typ dat události a odpovídající typ delegáta události. Například pokud chcete zpracovat událost MouseUp v aplikaci modelu Windows Forms, třída dat události je MouseEventArgs a delegát události je MouseEventHandler. Všimněte si, že několik událostí myši používá běžnou třídu pro data události a běžného delegáta události a schéma pojmenování tím pádem přesně neodpovídá výše uvedeným úmluvám. Pro události myši musí mít vaše obslužná rutina události následující signaturu:

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){}

Parametry odesílatel a argumenty události poskytují obslužné rutině události další podrobnosti o události myši. Objekt odesílatel označuje, co událost vyvolalo. Parametr MouseEventArgs poskytuje podrobné informace o pohybu myši, který událost vyvolal. Mnoho zdrojů událostí poskytuje události doplňující data a mnoho obslužných rutin událostí používá data specifická pro danou událost při jejím zpracování. Příklad ukazující vyvolání a zpracování události se specifickými daty naleznete v tématu Jak: Vyvolat a zpracovat události.

PoznámkaPoznámka

Události jsou vyvolávány také mimo kontext uživatelských rozhraní (UIs) a ve skutečnosti rozhraní .NET Framework obsahuje mnoho tříd bez uživatelského rozhraní, které události vyvolávají.Všechny události se však drží vzoru popsaného zde.

Informace o vyvolání událostí ze třídy naleznete v tématu Vyvolání události.

Statické a dynamické události

Rozhraní .NET Framework umožňuje odběratelům registraci k oznamování události staticky nebo dynamicky. Statické obslužné rutiny jsou platné po celou dobu životnosti třídy, jejíž události zpracovávají. Toto je nejběžnější způsob zpracování událostí. Dynamické obslužné rutiny událostí jsou explicitně aktivovány a deaktivovány během provádění programu, obvykle v rámci reakce na podmíněnou logiku programu. Například je lze použít v případě, že jsou oznámení událostí potřebné pouze za určitých podmínek nebo pokud aplikace poskytuje více obslužných rutin událostí a podmínky za běhu určí vhodnou rutinu, která se má použít.

Metoda EventInfo.AddEventHandler aktivuje dynamické obslužné rutiny události a metoda EventInfo.RemoveEventHandler je deaktivuje. Jednotlivé jazyky také poskytují vlastní funkce pro dynamické zpracování událostí. Následující příklad definuje třídu TemperatureMonitor, která vyvolává událost TemperatureTheshold vždy, když teplota dosáhne předdefinovaného prahu. Obslužná rutina události, která se přihlásí k této události, je pak aktivována a deaktivována během provádění programu.

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.

Viz také

Úkoly

Postupy: Zacházení s událostmi v aplikacích s webovými formuláři

Postupy: Zacházení s událostmi v aplikacích modelu Windows Forms

Koncepty

Události a Delegáti

Vyvolání události

Další zdroje

Zpracování a vyvolávání událostí