Pila observable y cola

Estoy buscando una implementación INotifyCollectionChanged de Stack and Queue . Podría hacer mi propio pero no quiero reinventar la rueda.

Con Stacks y Queues (casi por definición) solo tienes acceso a la parte superior de la stack o al encabezado de la cola. Es lo que los diferencia de una List . (y entonces, es por eso que no has encontrado uno)

Para responder que podría escribir el suyo, lo haría derivando de ObservableCollection , luego en el caso de una stack implementando Push como Insert en el desplazamiento 0 (y pop como índice de retorno 0 luego RemoveAt índice 0); o con una cola, puede Add al final de la lista a En Enqueue , y tomar y eliminar el primer elemento, como con la stack, para Dequeue . Las operaciones Insert , Add y RemoveAt serán llamadas a la ObservableCollection subyacente y provocarán que se RemoveAt el evento CollectionChanged .


También podría estar diciendo que simplemente desea vincular o ser notificado cuando cambia el único elemento al que se supone que tiene acceso. Debería crear su propia clase de nuevo, derivada de Stack o Queue, y desencadenar el evento CollectionChanged manualmente cuando:

  • Algo se empuja o se saca de una stack
  • Algo se retira de una cola
  • Algo se pone en cola en la cola, cuando la cola estaba previamente vacía

Me encuentro con el mismo problema y quiero compartir mi solución con otros. Espero que esto sea útil para alguien.

 public class ObservableStack : Stack, INotifyCollectionChanged, INotifyPropertyChanged { public ObservableStack() { } public ObservableStack(IEnumerable collection) { foreach (var item in collection) base.Push(item); } public ObservableStack(List list) { foreach (var item in list) base.Push(item); } public new virtual void Clear() { base.Clear(); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } public new virtual T Pop() { var item = base.Pop(); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item)); return item; } public new virtual void Push(T item) { base.Push(item); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item)); } public virtual event NotifyCollectionChangedEventHandler CollectionChanged; protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { this.RaiseCollectionChanged(e); } protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) { this.RaisePropertyChanged(e); } protected virtual event PropertyChangedEventHandler PropertyChanged; private void RaiseCollectionChanged(NotifyCollectionChangedEventArgs e) { if (this.CollectionChanged != null) this.CollectionChanged(this, e); } private void RaisePropertyChanged(PropertyChangedEventArgs e) { if (this.PropertyChanged != null) this.PropertyChanged(this, e); } event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged { add { this.PropertyChanged += value; } remove { this.PropertyChanged -= value; } } } 

Muy similar a la clase anterior, con algunas excepciones:

  1. Se modificó el prop de publicación para cambios en la recostackción de Count
  2. Anular TrimExcess () b / c que podría afectar el conteo
  3. He hecho públicos los eventos, así que no tengo que enviarlos a la interfaz
  4. Pasa el índice a la colección cambiado cuando es apropiado
  public class ObservableStack : Stack, INotifyPropertyChanged, INotifyCollectionChanged { public ObservableStack(IEnumerable collection) : base(collection) {} public ObservableStack() { } public event PropertyChangedEventHandler PropertyChanged = delegate { }; public event NotifyCollectionChangedEventHandler CollectionChanged = delegate { }; protected virtual void OnCollectionChanged(NotifyCollectionChangedAction action, List items, int? index = null) { if (index.HasValue) { CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, items, index.Value)); } else { CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, items)); } OnPropertyChanged(GetPropertyName(() => Count)); } protected virtual void OnPropertyChanged(string propName) { PropertyChanged(this, new PropertyChangedEventArgs(propName)); } public new virtual void Clear() { base.Clear(); OnCollectionChanged(NotifyCollectionChangedAction.Reset, null); } public new virtual T Pop() { var result = base.Pop(); OnCollectionChanged(NotifyCollectionChangedAction.Remove, new List() { result }, base.Count); return result; } public new virtual void Push(T item) { base.Push(item); OnCollectionChanged(NotifyCollectionChangedAction.Add, new List() { item }, base.Count - 1); } public new virtual void TrimExcess() { base.TrimExcess(); OnPropertyChanged(GetPropertyName(() => Count)); } String GetPropertyName(Expression> propertyId) { return ((MemberExpression)propertyId.Body).Member.Name; } }