Home > Software design >  MVVM ListBox won't update with filtered Collection
MVVM ListBox won't update with filtered Collection

Time:05-04

in XAML:   
<ListBox x:Name="AllJobListBox" MinHeight="200" MinWidth="500" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Path=AllJobList}" >

in CodeBehind: 
DataContext = new LoadJobWindowViewModel();
        //ctor where ObservableCollection is instantiated and populated

in ViewModel:      //bound to textbox on View
public string SearchText {
        get {
            return searchText;
        }
        set {
            searchText = value;
            OnPropertyChanged("SearchText");
        }
    }

Command:  
 public void SearchJob()
    {            
        ObservableCollection<Job> filteredJobs = new ObservableCollection<Job>(AllJobList.Where(j => j.JobName.Contains(SearchText)));
        AllJobList = filteredJobs;  
    }

I have been poring over blogs and posts trying to figure out what I have left out or done wrong, but can't put my finger on it. Any assistance at all would be appreciated.

CodePudding user response:

Make sure AllJobList raises the INotifyPropertyChanged.PropertyChanged event.

Your current solution is very expensive in terms of performance. You should always avoid to replace the complete source collection instance as it will force the ListBox to discard all containers and start a complete layout pass. Instead you want to use a ObservableCollection and modify it.
For this reason you should always prefer to filter and sort via the view of the collection (the ICollectionView). See Microsoft Docs: Data binding overview - Collection views. Manipulating the view also doesn't require to filter or sort the original collection:

ICollectionView allJobListView = CollectionViewSource.GetDefaultView(this.AllJobList);
allJobListView.Filter = item => (item as Job).JobName.Contains(this.SearchText);

Since a Binding always uses the view of a collection as source and not the collection itself (see the link above), the ListBox (or the ItemsSource Binding to be precise) will automatically update when assigning a Predicate<object> to the ICollectionView.Filter property.

  • Related