I’m trying to pivot my data by creating a ‘view’ of an Observable Collection based on certain criteria. Here’s a simple example.
I have two ListViews. One is bound directly to a collection of Dates, the other is bound to a DatesAfterToday collection derived from the first collection using Where(x => x.Date > DateTime.Today)
When I add a new item to my Dates collection, only the first ListView changes. The ListView bound to DatesAfterToday does not update at all. I’ve tried adding a PropertyChangedEventHandler to the viewmodel and firing it when the dates collection is updated, but it’s not working.
MainPage.xaml
<StackPanel>
<ListView x:Name="ListOne" ItemsSource="{Binding Dates}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Date}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView x:Name="ListTwo" ItemsSource="{Binding DatesAfterToday}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Date}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Click="Button_Click_1">Press Me to Add a Date</Button>
</StackPanel>
View Model
public class Model : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Model()
{
_Dates = new ObservableCollection<DateTime>();
}
private ObservableCollection<DateTime> _Dates;
public ObservableCollection<DateTime> Dates
{
get
{
return _Dates;
}
set
{
_Dates = value;
if (PropertyChanged != null){
PropertyChanged(this, new PropertyChangedEventArgs("_Dates"));
PropertyChanged(this, new PropertyChangedEventArgs("Dates"));
PropertyChanged(this, new PropertyChangedEventArgs("DatesAfterToday"));
}
}
}
public ObservableCollection<DateTime> DatesAfterToday
{
get {
return new ObservableCollection<DateTime>(
_Dates.Where(t => t.Date > DateTime.Today).ToList()
);
}
}
}
MainPage.xaml.cs
public sealed partial class ListTest : Page
{
public Model model;
public ListTest()
{
this.InitializeComponent();
model = new Model();
model.Dates.Add(new DateTime(2012, 11, 12, 0, 0, 0));
model.Dates.Add(new DateTime(2012, 11, 15, 0, 0, 0));
model.Dates.Add(new DateTime(2012, 11, 17, 0, 0, 0));
model.Dates.Add(new DateTime(2012, 11, 20, 0, 0, 0));
model.Dates.Add(new DateTime(2012, 11, 22, 0, 0, 0));
this.DataContext = model;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
model.Dates.Add(new DateTime(2012, 11, 24, 0, 0, 0));
}
}
UPDATE: Edited the question to make it a bit easier to read.
Modify your
Modelconstructor as follows:The thing is that when you add/remove items from the
_Datescollection, the setter won’t be called, and that’s why the property change event forDatesAfterTodayis never raised.For collections, WPF also registers for the
CollectionChangedevent, which is exposed by theINotifyCollectionChangedinterface implemented byObservableCollection. So what you can do is raise the notification forDatesAfterTodaywhenever the_Datescollection is modified.