I have a ListView
control that displays items from an observable collection. These items need to be filtered. I am able to do that with a CollectionViewSo
I like to use DataTriggers for that. For your logic would need to use a multivalue converter.
<ListView Grid.Row="3" Grid.Column="2" ItemsSource="{Binding Path=GabeLib.DocFieldsAll}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}" >
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Active}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=FieldDef.ID}" Value="0">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
Use a tool like ContinuousLinq. You bind your listview to a query that will reevaluate when an item in the list (or the list itself) changes.
Bind your ListView
directly to the filtered collection instead of the ObservableCollection by creating a property -
public ICollectionView YourFilteredCollection
{
get
{
var source = CollectionViewSource.GetDefaultView(collection.Collection);
source.Filter = p => Filter((ProjectViewModel)p);
return source;
}
}
So, now simply you need to call Refresh() on your collection on your check boxes state changed event like this -
YourFilteredCollection.Refresh();
To refresh the collection based on any state change in the item class, you can generalize it by hooking the PropertyChanged
event of your item class (for this your class need to implement INotifyPropertyChanged) and from there you can call refresh like this -
foreach (YourClass item in collection.Collection)
{
item.PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
}
void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
YourFilteredCollection.Refresh();
}
So, whenever any property changes in your item class, your collection will be filtered.