2010-09-28 8 views
1

J'ai une observableCollection et ai câblé un événement dans MyObject, y a-t-il un moyen cunnign de saisir cet événement dans la collection sans avoir à réécrire la classe de collection?Comment déclencher un événement lorsque l'objet d'élément de collection déclenche un événement

public class MyObjectCollection : ObservableCollection<MyObject> 
    { 
     public MyObjectCollection() 
     { 
      //some cunning code here 
     } 
    } 

Je pense que je dois réécrire la classe ObservableCollection, mais malheureusement il n'y a pas d'interface (comme il y a un IDictionary)

+0

"il n'y a pas d'interface": je ne comprends pas ce commentaire, que voulez-vous dire? –

Répondre

2

composition Faveur sur l'héritage. Au lieu d'étendre ObservableCollection, implémentez les interfaces dont vous avez besoin (probablement INotifyCollectionChanged et IList) et conservez ObservableCollection en tant que champ privé. De cette façon, vous pouvez câbler votre propre ajouter et supprimer des appels et faire ce que vous voulez avec les objets ajoutés à la collection.

+0

oui, c'est ce que je pensais. J'ai commencé cette route, mais je voulais juste vérifier qu'il n'y avait pas de 'magie' qui me manquait –

+0

Mind nous montrant une partie du code que vous avez fini dans cette solution? –

1

La lecture de ce nouveau, je pense que vous êtes après quelque chose comme ceci:

public sealed class CollectionEventMonitor<TItem, TEventArgs> : IDisposable 
    where TEventArgs: EventArgs 
{ 
    private readonly INotifyCollectionChanged _collection; 
    private readonly Action<TItem, EventHandler<TEventArgs>> _addEvent; 
    private readonly Action<TItem, EventHandler<TEventArgs>> _removeEvent; 

    public event EventHandler<TEventArgs> ItemFiredEvent; 

    public CollectionEventMonitor(INotifyCollectionChanged collection, 
     Action<TItem, EventHandler<TEventArgs>> addEvent, 
     Action<TItem, EventHandler<TEventArgs>> removeEvent) 
    { 
     _addEvent = addEvent; 
     _removeEvent = removeEvent; 
     _collection = collection; 
     _collection.CollectionChanged += _collection_CollectionChanged; 
    } 

    void _collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     switch (e.Action) 
     { 
      case NotifyCollectionChangedAction.Add: 
       foreach (var item in e.NewItems.Cast<TItem>()) 
        _addEvent(item, OnItemFiredEvent); 
       break; 
      case NotifyCollectionChangedAction.Remove: 
       foreach (var item in e.OldItems.Cast<TItem>()) 
        _removeEvent(item, OnItemFiredEvent); 
       break; 
      case NotifyCollectionChangedAction.Replace: 
       foreach (var item in e.OldItems.Cast<TItem>()) 
        _removeEvent(item, OnItemFiredEvent); 
       foreach (var item in e.NewItems.Cast<TItem>()) 
        _addEvent(item, OnItemFiredEvent); 
       break; 
      case NotifyCollectionChangedAction.Move: 
       break; 
      case NotifyCollectionChangedAction.Reset: 
       foreach (var item in e.OldItems.Cast<TItem>()) 
        _removeEvent(item, OnItemFiredEvent); 
       break; 
      default: 
       throw new ArgumentOutOfRangeException(); 
     } 
    } 

    private void OnItemFiredEvent(Object item, TEventArgs eventArgs) 
    { 
     var handler = ItemFiredEvent; 
     if (handler != null) 
      handler(item, eventArgs); 
    } 

    public void Dispose() 
    { 
     _collection.CollectionChanged -= _collection_CollectionChanged; 
    } 
} 

Ceci est rugueux et non testé, mais il devrait vous donner l'idée de base. Vous pouvez l'utiliser comme ceci:

 var collection = new ObservableCollection<Foo>(); 
     var monitor = 
      new CollectionEventMonitor<Foo, EventArgs>(collection, 
       (foo,handler) => foo.Bar += handler, 
       (foo,handler) => foo.Bar -= handler); 

L'avantage de cette approche est que vous pouvez suivre toute collection observable pour les événements de l'objet, plutôt que de créer une collection d'emballage spécial. Vous pouvez également créer plusieurs instances du moniteur pour la même collection, ce qui permet à différents contextes de surveiller différents événements d'éléments de la même collection.

+0

Merci c'est très créatif. Je pense que je vais aller avec l'option A, je pense que l'encapsulation est meilleure avec l'option A, et la maintenabilité. Cependant, je vais classer celui-ci comme je pense qu'il peut être utile dans des scénarios plus complexes. –

Questions connexes