Estoy buscando una implementación INotifyCollectionChanged
de Stack
y Queue
. Podría hacer mi propio pero no quiero reinventar la rueda.Observable Stack and Queue
Respuesta
Con pilas y colas (casi por definición) solo tiene acceso a la parte superior de la pila o cabeza de la cola. Es lo que los diferencia de List
. (Y por lo tanto, es por eso que no ha encontrado uno)
Para responder a pesar de que podría escribir su propia, lo haría mediante la derivación de ObservableCollection
, a continuación, en el caso de una pila aplicación del Push
como Insert
en el offset 0 (y pop como índice de retorno 0 luego RemoveAt
índice 0); o con una cola puede simplemente Add
hasta el final de la lista a Enqueue
, y tomar y quitar el primer elemento, como con la pila, para Dequeue
. Se llamaría a las operaciones Insert
, Add
y RemoveAt
en el ObservableCollection
subyacente y provocaría el desencadenamiento del evento CollectionChanged
.
También puede ser que diga que simplemente quiere unirse o ser notificado cuando el único elemento que se supone que tienen acceso a los cambios. Se podría crear su propia clase de nuevo, derivado de la pila o cola, y desencadenar el evento CollectionChanged manualmente cuando:
- Algo se empuja sobre o surgió a partir de una pila
- Algo se quita de la cola de una cola
- Algo se pone 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<T> : Stack<T>, INotifyCollectionChanged, INotifyPropertyChanged
{
public ObservableStack()
{
}
public ObservableStack(IEnumerable<T> collection)
{
foreach (var item in collection)
base.Push(item);
}
public ObservableStack(List<T> 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; }
}
}
Hola. Tener un error después de Pop() "El evento Collection Remove debe especificar la posición del elemento". ¿Cualquier forma de arreglar esto? tnx –
base.Count como la posición del artículo faltante lo arregló para mí. public new virtual T Pop() { var item = base.Pop(); this.OnCollectionChanged (nuevo NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Remove, item, base.Count)); artículo devuelto; } – uli78
Prefiero esta solución a la respuesta aceptada. Le permite mantener las expectativas de rendimiento y la semántica de Stack/Queue, en lugar de simplemente simularlo con una lista (que, por ejemplo, es caro de eliminar desde el principio, en comparación con una cola). – KChaloux
Muy similar a la clase anterior, con algunas excepciones:
- Publish prop cambiado para cambios de recogida para el recuento de
- Override TrimExcess() b/c que podría afectar Count
- Hechos públicos para que no tenga que enviar a la interfaz
- Pasa el índice a la colección cambiado cuando corresponde
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(ClrExtensions.PropertyName(() => 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(ClrExtensions.PropertyName(() => Count));
}
}
- 1. Stack and Queue, ¿Por qué?
- 2. JVM - Heap and Stack
- 3. Threading Heap and Stack
- 4. C++ deque vs queue vs stack
- 5. Azure Blob and Queue Thread Safety
- 6. Service stack and Mocking, any tutorials?
- 7. Deshacer/Rehacer usando Memento: Stack, Queue o simplemente LinkedList?
- 8. Stack Stack
- 9. ¿Por qué Queue (T) y Stack (T) no implementan ICollection (T)?
- 10. ¿Por qué Stack <T> y Queue <T> se implementan con una matriz?
- 11. ¿por qué Stack es una clase mientras Queue es una interfaz?
- 12. Eliminación observable de la suscripción observable
- 13. Queue ordinario frente a SEDA Queue
- 14. Message Queue vs Task Queue difference
- 15. erlang call stack
- 16. WSMQ Queue Limit
- 17. Cómo copiar colección observable
- 18. Observable Red IO Parsing
- 19. ¿Alternativa al patrón observable?
- 20. contenedor observable para C++
- 21. Filtrar una colección observable
- 22. Observable en Java
- 23. NSRunningApplication 'terminated' not Observable
- 24. Solo lectura colección observable
- 25. Observable Colección reemplazar elemento
- 26. esperando en un observable
- 27. (OrElse and Or) and (AndAlso and And) - ¿Cuándo usar?
- 28. Inserters para STL stack y priority_queue
- 29. ¿Cuál es la diferencia entre Call Stack y Stack Trace?
- 30. Event/Task Queue Multithreading C++
Recomiendo el primer acercamiento para 'ObservableStack' - deriva de (o mejor, contiene) un' ObservableCollection'. El segundo enfoque sería mejor para 'ObservableQueue': deriva de' Queue' e implementa tus propias notificaciones. Esto se debe a que cualquier 'ObservableQueue' construido en una' List' tendrá un rendimiento O (N) para 'Enqueue' o 'Dequeue', mientras que todo lo demás será O (1). Esto tendría un impacto en el rendimiento si hay muchos elementos en la cola. –
Decidí hacer una clase observable genérica que simplemente implementara INotifyCollectionChanged. Las clases llaman a los métodos internos de pila y cola y generan el evento apropiado. Favorecer la composición sobre la herencia, ya que los métodos Stack y Cola no son virtuales (lo que me cuesta entender por qué). – Goran