I have a ListView called ChosenListView in my UserControl. In my UserControl's constructor I set the DataContext to my ViewModel, which includes an ObservableCollection (called Elements) of elements that have a bool IsChosen property.
I want to have my ChosenListView display all elements in Elements whose IsChosen property is true. I want it to be automatically updated every time I change one of the elements IsChosen property.
I tried to utilize INotifyPropertyChanged, but I can't seem to get it to work and would appreciate any help.
I define here a CollectionViewSource:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<CollectionViewSource
x:Key="ChosenElementsViewSource"
x:Name="ChosenElementsViewSource"
Source="{Binding Elements}"
Filter="ChosenElementsViewSource_Filter"/>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
This is the filter:
private void ChosenElementsViewSource_Filter(object sender, FilterEventArgs e)
{
e.Accepted = e.Item is ChoosableElement choosableElement &&
choosableElement.IsChosen;
}
This is my ViewModel:
private class ViewModel
{
public ObservableCollection<ChoosableElement> Elements { get; set; }
}
In my UserControl's constructor I set DataContext to a new instance of my ViewModel, and initialize Elements based on my database, where all elements start with IsChosen=false.
My ListView defines an ItemsSource in the XAML:
ItemsSource="{Binding Source={StaticResource ChosenElementsViewSource}}"
Lastly, my ChoosableElement is defined as follows:
private class ChoosableElement : INotifyPropertyChanged
{
public Element Element { get; set; }
private bool isChosen = false;
public bool IsChosen
{
get { return isChosen; }
set
{
if (isChosen != value)
{
isChosen = value;
OnPropertyChanged(nameof(IsChosen));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
You need to refresh the
CollectionViewSourceto invoke theFilterevent handler each time theIsChosenproperty is set.You can either do this programmatically yourself by handling the
PropertyChangedevent for all items in the code-behind of theUserControl. Something like this:Or you could enabling the live filtering feature that was introduced in the .NET Framework 4.5 directly on the
CollectionViewSourcein the XAML markup: