C#:
public partial class MainWindow : Window
{
private readonly ViewModel vm;
public MainWindow()
{
InitializeComponent();
vm = new ViewModel();
DataContext = vm;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
vm.Models.RemoveAt(0);
}
}
public class ViewModel
{
public ObservableCollection<Model> Models { get; set; }
public ListCollectionView View { get; set; }
public ViewModel()
{
Models = new ObservableCollection<Model>()
{
new Model() { Name = "Gordon Freeman" },
new Model() { Name = "Isaac Kleiner" },
new Model() { Name = "Eli Vance" },
new Model() { Name = "Alyx Vance" },
};
Models.CollectionChanged += (s, e) => View.Refresh();
View = new ListCollectionView(Models);
}
}
public class Model
{
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
XAML:
<StackPanel>
<ListBox ItemsSource="{Binding Path=View}" />
<Button Click="Button_Click">Click</Button>
</StackPanel>
The ObservableCollection contains 4 elements, and the ListBox is displaying all 4, as expected. When the button is clicked, the 1st element of the ObservableCollection is removed. The ListBox, however, is now displaying only the 2nd and 3rd. It would appear the 1st and 4th have been removed.
If the line Models.CollectionChanged += (s, e) => View.Refresh();
is moved after View = new ListCollectionView(Models);
(or commented out entirely) things work as expected.
Why?
P.S. This is a simple piece of a larger puzzle. In this small example, I realize I don't need to call View.Refresh();
on CollectionChanged for the ListBox to update itself.
Try not to use the new keyword to define your new instance of
listCollectionView
. Use the following instead.