2008-10-20 12 views
7

Se ho una proprietà:C# gestori di eventi personalizzati

public list<String> names { get; set; } 

Come posso generare e gestire un evento personalizzato per amor di argomenti chiamato 'onNamesChanged' ogni volta che un nome viene aggiunto alla lista?

risposta

-1

Non è necessario esporre l'elenco direttamente come una proprietà e forse avere la classe implementare IList o alcuni di essi quindi attivare il gestore di eventi sul metodo Add().

+0

Questo è così .NET 1.1 :) Come Marc Gravell ha detto ... molto lavoro, poco beneficio. –

0

David Mohundro mostra un approccio; un'altra possibilità è quella di ereditare da Collezione <T> e sovrascrivere i vari metodi:

class Foo {} 
class FooCollection : Collection<Foo> 
{ 
    protected override void InsertItem(int index, Foo item) 
    { 
     // your code... 
     base.InsertItem(index, item); 
    } 
    protected override void SetItem(int index, Foo item) 
    { 
     // your code... 
     base.SetItem(index, item); 
    } 
    // etc 
} 

Infine, è possibile creare il proprio elenco (IList, IList <T>) da principi primi - un sacco di lavoro, pochi benefici .

13

Un BindingList è probabilmente l'opzione migliore in quanto ha incorporato il rilevamento delle modifiche e una varietà di eventi esistenti che è possibile utilizzare. Di seguito è riportato un esempio di esposizione di un evento personalizzato per Aggiungi che inoltra all'evento BindingList.


    class Example 
    { 
     private BindingList<string> m_names = new BindingList<string>(); 
     public IEnumerable<string> Names { get { return m_names; } } 
     public event AddingNewEventHandler NamesAdded 
     { 
      add { m_names.AddingNew += value; } 
      remove { m_names.AddingNew -= value; } 
     } 
     public void Add(string name) 
     { 
      m_names.Add(name); 
     } 
    } 
+1

Dang. Imparo un'altra cosa nuova oggi. :) –

+1

Whoa, non sapevo che potessi farlo con gli eventi! Quello è abbastanza elegante! –

+1

Molto bello. Non avevo idea che fosse possibile – Steve

10

Un'alternativa al BindingList è ObservableCollection - in questo caso ci si vuole iscriversi il proprio gestore di eventi per l'evento CollectionChanged e licenziare il tuo evento a seconda dell'azione.

+0

Un altro voto qui. Non riesco ancora a smettere di imparare :) –

0

Un approccio non ortodosso potrebbe utilizzare un framework AOP come PostSharp per "tessere" un gestore prima/dopo che l'accessor viene chiamato, che attiva un evento.

È possibile creare una classe esterna contenente il codice di gestione pre e/o post per l'accesso alla proprietà, verificare se il valore della proprietà è cambiato tra pre e post e generare un evento.

Tenere presente che durante l'acquisizione del valore per il confronto (all'interno del codice del gestore), è possibile entrare in un ciclo infinito (si chiama la proprietà accessor, che chiama il gestore AOP, che chiama l'accessor e così via), quindi potrebbe essere necessario riflettere nella classe contenente questa proprietà per ottenere il campo di supporto.