Ok so i had trouble even expressing what I needed so i had to build it myself. So what is it?
Well, it’s basically a hashed queue where when you enqueue again an already queued item, you basically put it in the first spot. It’s made as a collection but it still acts as a queue. I needed it for my taskbar which automatically closes the least active item, or the one least used. so here you go:
public class BindableQueueSet<T> : ICollection<T>, INotifyCollectionChanged,INotifyPropertyChanged { private readonly ObservableCollection<Pair> que; private int maxNumber; private readonly int capacity; #region Private and protected private bool AddItemCore(T item) { bool result; var found = que.FirstOrDefault(x => x.Value.Equals(item)); if (found == null) { que.Add(new Pair(item, maxNumber++)); result = true; } else { found.Weight = maxNumber++; result = false; } result = CleanUp() || result; return result; } private Pair Find(T item) { return que.FirstOrDefault(x => x.Value.Equals(item)); } private bool CleanUp() { if (capacity >= que.Count) return false; Pair lightestPair = que[0]; foreach (var pair in que) { if (pair.Weight < lightestPair.Weight) lightestPair = pair; } que.Remove(lightestPair); return true; } #endregion public BindableQueueSet(int capacity) { if (capacity < 1) throw new ArgumentException(); this.capacity = capacity; que = new ObservableCollection<Pair>(); que.CollectionChanged += (s, e) => OnCollectionChanged(e); ((INotifyPropertyChanged) que).PropertyChanged += (s, e) => OnPropertyChanged(e); } private void OnPropertyChanged(PropertyChangedEventArgs e) { if (PropertyChanged != null) PropertyChanged(this, e); } void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { NotifyCollectionChangedEventArgs enew; switch (e.Action) { case NotifyCollectionChangedAction.Replace: enew = new NotifyCollectionChangedEventArgs(e.Action, e.NewItems != null && e.NewItems.Count > 0 ? ((Pair) e.NewItems[0]).Value:default(T), e.OldItems != null && e.OldItems.Count > 0 ? ((Pair) e.OldItems[0]).Value:default(T), e.NewStartingIndex); break; case NotifyCollectionChangedAction.Add: enew = new NotifyCollectionChangedEventArgs(e.Action, e.NewItems != null && e.NewItems.Count > 0 ? ((Pair)e.NewItems[0]).Value : default(T), e.NewStartingIndex); break; case NotifyCollectionChangedAction.Remove: enew = new NotifyCollectionChangedEventArgs(e.Action, e.OldItems != null && e.OldItems.Count > 0 ? ((Pair)e.OldItems[0]).Value : default(T), e.OldStartingIndex); break; default: enew = new NotifyCollectionChangedEventArgs(e.Action); break; } if (CollectionChanged != null) CollectionChanged(this, enew); } public IEnumerator<T> GetEnumerator() { return new QueueEnum(que.GetEnumerator()); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public void Add(T item) { AddItemCore(item); } public void Clear() { que.Clear(); } public bool Contains(T item) { return Find(item) != null; } public void CopyTo(T[] array, int arrayIndex) { while (arrayIndex < array.Length) { AddItemCore(array[arrayIndex]); arrayIndex++; } } public bool Remove(T item) { var found = Find(item); return que.Remove(found); } public int Count { get { return que.Count; } } public bool IsReadOnly { get { return false; } } public event NotifyCollectionChangedEventHandler CollectionChanged; private class Pair { public int Weight { get; set; } public T Value { get; private set; } public Pair(T value, int weight) { Value = value; Weight = weight; } } private class QueueEnum : IEnumerator<T> { private readonly IEnumerator<Pair> queEnum; public QueueEnum(IEnumerator<Pair> queEnum) { this.queEnum = queEnum; } public void Dispose() { queEnum.Dispose(); } public bool MoveNext() { return queEnum.MoveNext(); } public void Reset() { queEnum.Reset(); } public T Current { get { return queEnum.Current.Value; } } object IEnumerator.Current { get { return Current; } } } public event PropertyChangedEventHandler PropertyChanged; }
Leave a Comment