あるいは変更通知付きのコレクションを使うとそういった手間が省けます。
ObservableStack<T> があるようです(試してはいません)
試してみました。
紹介しておいてなんですが、WPFではあまりテストしていなそうで現時点では自分で用意したほうがよさそうでした(既存アイテムがタプルとして表示されてしまう等)
WPF example is behaving weirdly · Issue #7 · Cysharp/ObservableCollections
例えばこの辺りを使わせてもらうとこんな感じです。
c# - Observable Stack and Queue - Stack Overflow
xml
1<Window
2 x:Class="Questions361141.MainWindow"
3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5 Width="800"
6 Height="450">
7 <DockPanel>
8 <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
9 <Button Click="PushButton_Click" Content="Push" />
10 <Button Click="PopButton_Click" Content="Pop" />
11 </StackPanel>
12 <ListView x:Name="listView" />
13 </DockPanel>
14</Window>
cs
1using System.Collections.Generic;
2using System.Collections.Specialized;
3using System.ComponentModel;
4using System.Windows;
5
6namespace Questions361141
7{
8 // [c# - Observable Stack and Queue - Stack Overflow](https://stackoverflow.com/questions/3127136/observable-stack-and-queue/56177896#56177896)
9 public class ObservableStack<T> : Stack<T>, INotifyCollectionChanged, INotifyPropertyChanged
10 {
11 public ObservableStack() : base() { }
12 public ObservableStack(IEnumerable<T> collection) : base(collection) { }
13 public ObservableStack(int capacity) : base(capacity) { }
14
15 public new virtual T Pop()
16 {
17 var item = base.Pop();
18 OnCollectionChanged(NotifyCollectionChangedAction.Remove, item);
19 return item;
20 }
21 public new virtual void Push(T item)
22 {
23 base.Push(item);
24 OnCollectionChanged(NotifyCollectionChangedAction.Add, item);
25 }
26 public new virtual void Clear()
27 {
28 base.Clear();
29 OnCollectionChanged(NotifyCollectionChangedAction.Reset, default);
30 }
31
32 public virtual event NotifyCollectionChangedEventHandler CollectionChanged;
33 protected virtual void OnCollectionChanged(NotifyCollectionChangedAction action, T item)
34 {
35 CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(action, item, item == null ? -1 : 0));
36 OnPropertyChanged(nameof(Count));
37 }
38
39 public virtual event PropertyChangedEventHandler PropertyChanged;
40 protected virtual void OnPropertyChanged(string proertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(proertyName));
41 }
42
43
44 public partial class MainWindow : Window
45 {
46 private readonly ObservableStack<int> numbers;
47
48 public MainWindow()
49 {
50 InitializeComponent();
51
52 numbers = new ObservableStack<int>();
53 numbers.Push(1);
54 numbers.Push(2);
55 numbers.Push(3);
56
57 listView.ItemsSource = numbers;
58 }
59
60 private void PushButton_Click(object sender, RoutedEventArgs e)
61 => numbers.Push(numbers.Count + 1);
62 private void PopButton_Click(object sender, RoutedEventArgs e)
63 => numbers.Pop();
64 }
65}