2012-03-27 19 views
19

È possibile creare un evento personalizzato per qualsiasi metodo di oggetto?
Per fare questo posso solo utilizzare la seguente sintassi ?:Creazione di un evento personalizzato

myObject.myMethod +=new EventHandler(myNameEvent); 

Il seguente codice ha spinto a questa domanda:

private void btRunProcessAndRefresh_Click(object sender,EventArgs e) 
    { 
     myProcess =new Process(); 
     myProcess.StartInfo.FileName = @"c:\ConsoleApplication4.exe"; 
     myProcess.Exited += new EventHandler(MyProcessExited); 
     myProcess.EnableRaisingEvents =true; 
     myProcess.SynchronizingObject =this; 
     btRunProcessAndRefresh.Enabled =false; 
     myProcess.Start(); 
    } 
+2

check out il [esempio MSDN] (http://msdn.microsoft.com/it/us/library/aa645739 (VS.71) .aspx) degli eventi e – Default

+0

nota che 'myProcess.Exited + = MyProcessExited;' è sufficiente. – Default

+0

@Default ahhhh .... quindi potrei avere 'myProcess.Exited + = new EventHandler (MyProcessExited);' O potrei dichiarare l'evento e quindi usare 'myProcess.Exited + = MyProcessExited;'? – whytheq

risposta

16

Sì che si può fare in questo modo:

Creating advanced C# custom events

o

The Simplest C# Events Example Imaginable

public class Metronome 
    { 
     public event TickHandler Tick; 
     public EventArgs e = null; 
     public delegate void TickHandler(Metronome m, EventArgs e); 
     public void Start() 
     { 
      while (true) 
      { 
       System.Threading.Thread.Sleep(3000); 
       if (Tick != null) 
       { 
        Tick(this, e); 
       } 
      } 
     } 
    } 
    public class Listener 
    { 
     public void Subscribe(Metronome m) 
     { 
      m.Tick += new Metronome.TickHandler(HeardIt); 
     } 

     private void HeardIt(Metronome m, EventArgs e) 
     { 
      System.Console.WriteLine("HEARD IT"); 
     } 
    } 
    class Test 
    { 
     static void Main() 
     { 
      Metronome m = new Metronome(); 
      Listener l = new Listener(); 
      l.Subscribe(m); 
      m.Start(); 
     } 
    } 
+22

che non sembra l'esempio più semplice per me. – Default

+0

@Default - controlla il primo collegamento con l'esempio più semplice –

+0

è meglio :) – Default

1

È necessario dichiarare il vostro evento nella classe da myObject:

then myNameEvent è il callback per gestire l'evento e può essere in qualsiasi altra classe

.210
+0

ok ma la domanda è stata ispirata da un codice che sto analizzando. Aggiungerò il codice alla domanda. Non vedo nessuna dichiarazione. – whytheq

+0

Bene se si fa clic su Vai a definizione su Esci, deve essere un evento, quindi il codice di gestione è in MyProcessExited. – MBen

22

dichiarare la classe che contiene l'evento:

class MyClass { 
    public event EventHandler MyEvent; 

    public void Method() { 
     OnEvent(); 
    } 

    private void OnEvent() { 
     if (MyEvent != null) { 
      MyEvent(this, EventArgs.Empty); 
     } 
    } 
} 

usare in questo modo :

MyClass myObject = new MyClass(); 
myObject.MyEvent += new EventHandler(myObject_MyEvent); 
myObject.Method(); 
+3

+1 bel esempio semplice - grazie – whytheq

11

Sì, è possibile creare eventi sugli oggetti, ecco un esempio;

public class Foo 
{ 
    public delegate void MyEvent(object sender, object param); 
    event MyEvent OnMyEvent; 

    public Foo() 
    { 
     this.OnMyEvent += new MyEvent(Foo_OnMyEvent); 
    } 

    void Foo_OnMyEvent(object sender, object param) 
    { 
     if (this.OnMyEvent != null) 
     { 
      //do something 
     } 
    } 



    void RaiseEvent() 
    { 
     object param = new object(); 
     this.OnMyEvent(this,param); 
    } 
} 
+1

Guardo alcuni degli altri esempi forniti e non includono "delegato" - che non ho incontrato prima di – whytheq

+2

quando guardi l'EventHandler, è solo un delegato specifico. – daryal

+0

da esporre, è necessario utilizzare un delegato gestore di eventi personalizzato solo se sono necessari parametri diversi da quelli utilizzati per ['EventHandler'] (https://msdn.microsoft.com/en-us/library/system.eventhandler (v = vs.110) .aspx) o ['EventHandler <>'] (https://msdn.microsoft.com/en-us/library/db0etb8x (v = vs.110) .aspx). Vedi [here] (http://csharpindepth.com/Articles/Chapter2/Events.aspx) per i dettagli. – kdbanman

4

Sì, purché si disponga di accesso alla definizione dell'oggetto e possibile modificarlo per dichiarare l'evento personalizzato

public event EventHandler<EventArgs> ModelChnaged; 

e normalmente ci si eseguire questo con un metodo privato utilizzato internamente per invocare la evento:

private void OnModelChanged(EventArgs e) 
{ 
    if (ModelChnaged != null) 
     ModelChnaged(this, e); 
} 

tuo codice dichiara semplicemente un gestore per l'evento dichiarato myMethod (è possibile anche rimuovere il costruttore), che andrebbe invocato ogni volta che il l'oggetto fa scattare l'evento.

myObject.myMethod += myNameEvent; 

Allo stesso modo, è possibile staccare un gestore utilizzando

myObject.myMethod -= myNameEvent; 

Inoltre, è possibile scrivere il proprio subclass of EventArgs di fornire i vostri dati generato l'evento specifico quando.

+0

Semplice ed elegante. –

+0

Ho provato, ma l'evento non ha sparato – user688

2

In base alla risposta di @ ionden, la chiamata al delegato potrebbe essere semplificata utilizzando propagazione null da C# 6.0.

Il tuo codice sarebbe semplicemente:

class MyClass { 
    public event EventHandler MyEvent; 

    public void Method() { 
     MyEvent?.Invoke(this, EventArgs.Empty); 
    } 
} 

usare in questo modo:

MyClass myObject = new MyClass(); 
myObject.MyEvent += new EventHandler(myObject_MyEvent); 
myObject.Method(); 
Problemi correlati