Where have I gone wrong with my implementation of a ObservableStack<T>
? The XAML is failing to bind to it some how and so the information contained in the stack is not showing in the UI. If I only change the type of the property in the ViewModel from my ObservableStack<T>
to ObservableCollection<T>
then the UI elements appear. This makes me think it's the implementation.
I want to use this so my elements appear in the UI in Stack order and not collection order.
Here is my implementation:
public class ObservableStack<T> : INotifyPropertyChanged, INotifyCollectionChanged, ICollection , IEnumerable<T>, IEnumerable , IReadOnlyCollection<T>
{
ObservableCollection<T> _coll = new ObservableCollection<T>();
public ObservableStack()
{
_coll.CollectionChanged += _coll_CollectionChanged;
}
public ObservableStack(IEnumerable<T> items) : base()
{
foreach (var item in items)
{
Push(item);
}
}
private void _coll_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
OnCollectionChanged(e);
}
public void Push(T item)
{
_coll.Insert(0, item);
}
public void Pop()
{
_coll.RemoveAt(0);
}
public T Peek
{
get { return _coll[0]; }
}
public int Count
{
get
{
return ((ICollection)_coll).Count;
}
}
public bool IsSynchronized
{
get
{
return ((ICollection)_coll).IsSynchronized;
}
}
public object SyncRoot
{
get
{
return ((ICollection)_coll).SyncRoot;
}
}
public void CopyTo(Array array, int index)
{
((ICollection)_coll).CopyTo(array, index);
}
public IEnumerator GetEnumerator()
{
return ((ICollection)_coll).GetEnumerator();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return ((IEnumerable<T>)_coll).GetEnumerator();
}
#region INotifyPropertyChanged
protected void OnPropertyChanged([CallerMemberName] string caller = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(caller));
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region INotifyCollectionChanged
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
CollectionChanged?.Invoke(this, e);
}
#endregion
}
The solution I've found is that I needed to implement IList on my ObservableStack. After that everything worked as expected. Curiously, just implementing IList<T>
didn't work. It needed the non generic interface. Thanks again to those who offered help.