I’m sure there is good explanation for this. I’m guessing it has something to do with me having a cold and missing something obvious…
I have a simple window:
<Window x:Class="WpfIdeas.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:w="clr-namespace:WpfIdeas"
Title="Window1" Height="300" Width="315">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" x:Name="btnAddObject" Click="btnAddObject_Click">Add Object</Button>
<ListView Grid.Row="1" ItemsSource="{Binding Objects}">
</ListView>
</Grid>
</Window>
the code behind the window is:
using System.Windows;
namespace WpfIdeas
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
DataContext = new ObjectVM();
}
private void btnAddObject_Click(object sender, RoutedEventArgs e)
{
(DataContext as ObjectVM).AddObject();
}
}
}
And its DataContext is set to be the following class:
class ObjectVM : INotifyPropertyChanged
{
private readonly List<ObjectModel> objects = new List<ObjectModel>();
//public IEnumerable<ObjectModel> Objects { get { return objects } } //doesn't work
public IEnumerable<ObjectModel> Objects { get { return objects.ToList() } } //works
private Random r = new Random();
public void AddObject()
{
ObjectModel o = new ObjectModel(r);
objects.Add(o);
if(PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Objects"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
The ObjectModel class is in fact a struct that generates a 14 character string when it is instantiated. It’s ToString() method just outputs this string.
As the code is above, when I click the “Add Object” button then a new string appears in the ListView.
However if I remove the ToList() call in the Objects property, nothing is ever displayed in the ListView. It just remains blank.
Why is this?
Using Collection Objects as a Binding Source:
You can enumerate over any collection that implements the IEnumerable interface. However, to set up dynamic bindings so that insertions or deletions in the collection update the UI automatically, the collection must implement the INotifyCollectionChanged interface. This interface exposes an event that must be raised whenever the underlying collection changes.