This project has moved. For the latest updates, please go here.

AgFx + CollectionViewSource.View.Filter = No Refresh

May 11, 2012 at 7:20 PM

I'm trying to use CollectionViewSource.View.Filter in order to filter results for a search on an ObservableCollection within a ViewModel with ModelItemBase as the base. I believe my implementation is fairly standard for AgFx aside from that.

The filtering code is hit & the logic returns the correct boolean value iterating through the dataset, but the items displayed in the ListBox with the CollectionViewSource.View are never changed to reflect the filtered list that I've checked to be containing the correct items.  I also tried switching out the ViewModel with a generic one with data hard-coded rather than one based on ModelItemBase and the filtering works perfectly, so I know it's something with AgFx.

Has anyone ever used CollectionViewSource with AgFx successfully? Any suggestions on getting this to work? It seems so simple, and yet it's not working.

Thanks.

MainViewModel.cs:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
// Added
using System.Collections.ObjectModel;
using AgFx;
using Airman_s_Airports.Services;
using System.Windows.Data;

namespace Airman_s_Airports.ViewModels
{
    [CachePolicy(CachePolicy.CacheThenRefresh, 60 * 60 * 24 * 15)]
    public class MainViewModel : ModelItemBase<MainLoadContext>
    {
        public MainViewModel()
        {
        }

        public MainViewModel(string uri)
            : base(new MainLoadContext(uri))
        {

        }

        private BatchObservableCollection<Airport> _airports = new BatchObservableCollection<Airport>();

        public ObservableCollection<Airport> Airports
        {
            get { return _airports; }
            set
            {
                if (_airports != null)
                {
                    _airports.Clear();
                    if (value != null && value != _airports)
                        foreach (var apt in value)
                            _airports.Add(apt);
                    RaisePropertyChanged("Airports");
                }
            }
        }

        private CollectionViewSource _filteredAirports;

        public CollectionViewSource FilteredAirports
        {
            get {
                if (_filteredAirports == null)
                    _filteredAirports = new CollectionViewSource();
                _filteredAirports.Source = _airports;

                return _filteredAirports; }
            set { _filteredAirports = value; }
        }

        private string _filterText;

        public string FilterText
        {
            get {
                return _filterText; }
            set
            {
                _filterText = value;
                RaisePropertyChanged("FilterText");
                UpdateFilter();
            }
        }

        private void UpdateFilter()
        {
            if (FilterText != null && FilterText != "")
            {
                FilteredAirports.View.Filter = a =>
                {
                    if (a == null)
                        return true;
                    var apt = (Airport)a;
                    var accepted = apt.Name.ToLowerInvariant().Contains(FilterText.ToLowerInvariant());
                    return accepted;
                };
            }
        }

        public class MainViewModelLoader : IDataLoader<MainLoadContext>
        {
            public LoadRequest GetLoadRequest(MainLoadContext loadContext, Type objectType)
            {
                if (!App.Settings.IsLocalDataFirstLoadComplete)
                    return new LocalLoadRequest(loadContext, loadContext.Uri);
                else
                    return new WebLoadRequest(loadContext, new Uri(loadContext.Uri));
            }

            public object Deserialize(MainLoadContext loadContext, Type objectType, System.IO.Stream stream)
            {
                var aptsToAdd = XMLParser.FromFAAAirports(stream);
                var vm = new MainViewModel(loadContext.Uri);
                foreach (var newapt in aptsToAdd)
                {
                    vm.Airports.Add(new Airport(newapt));
                }
                return vm;
            }
        }
    }
}

MainPage.xaml.cs (excerpt):

        public MainPage()
        {
            InitializeComponent();
            DataContext = DataManager.Current.Load<MainViewModel>(App.webUri);
            //DataContext = new AltMainViewModel();
        }

MainPage.xaml (excerpt):

<ListBox x:Name="airportListBox" ItemTemplate="{StaticResource AirportTemplate}" 
ItemsSource="{Binding FilteredAirports.View}" 
Grid.Row="2" Margin="12,0,0,0"/>
May 12, 2012 at 5:11 AM

You might as well delete this thread, because I foolishly overlooked the fact that I did not call RaisePropertyChanged("FilteredAirports"); in _filteredAirports.set().  :$

Coordinator
May 12, 2012 at 4:24 PM

Done. :)