wpfobservablecollectionicollectionview

why does my ObservableCollection not filter


i have a WPF desktop app.

I load an ObservableCollection with a list of objects.

I use the ICollectionView object to 'wrap' a filter around this ObservableCollection .

I set the filter and refresh but it does nto work so:

public class DataFilters : ViewModelBase
{
    private ICollectionView _UserMappedRolesView { get; set; }

    private ObservableCollection<UserMappedRoles> _UserMappedRoles;
    public ObservableCollection<UserMappedRoles> UserMappedRoles
    {
        get
        {
            _UserMappedRolesView = CollectionViewSource.GetDefaultView(_UserMappedRoles);
            _UserMappedRolesView.Filter = UserMappedRolesFilter;
            _UserMappedRolesView.Refresh();
            return _UserMappedRoles;
        }
        set
        {
            _UserMappedRoles = value;
        }
    }

    public void LoadUserMappedRoles()
    {
        var baseData = InformedWorkerBusinessService.UserMappedRoles.Get();
        var modelData =
            from data in baseData
            select new UserMappedRoles
            {
                Enabled = 1,
                Login = data.Login,
                UserMappedRolesRef = data.UserMappedRolesRef,
                UserRoleRef = data.UserRoleRef

            };
        _UserMappedRoles = new ObservableCollection<UserMappedRoles>(modelData);
    }
    public string Login { get; set; }
    private bool UserMappedRolesFilter(object item)
    {
        UserMappedRoles UserMappedRole = item as UserMappedRoles;

        if (UserMappedRole.Login== Login)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

and my test script:

UI.InformedWorkerViewModel.Models.HeartBeat VM = new UI.InformedWorkerViewModel.Models.HeartBeat();
VM.CommonData.DataFilters = new UI.InformedWorkerViewModel.Models.DataFilters();
VM.CommonData.DataFilters.LoadUserMappedRoles();
var data = VM.CommonData.DataFilters.UserMappedRoles;
VM.CommonData.DataFilters.Login = "David";
var filtered = VM.CommonData.DataFilters.UserMappedRoles;

I know my data only contains oUserMappedRoles where the Login name is 'Andy' so, by setting the Login filter name to 'David' I expect to get no records back.

I have set breakpoints everywhere and everyline of code gets 'hit'.

Have I (obviously) implemented this wrong?

Thanks


Solution

  • It is the ICollectionView that gets filtered, not the ObservableCollection.

    So you should bind to the ICollectionView property:

    <ListBox ItemsSource="{Binding UserMappedRolesView}" DisplayMemberPath="Login" />
    

    ...or look for the filtered items in this one:

    var filtered = VM.CommonData.DataFilters.UserMappedRolesView;
    

    You also need to refresh the CollectionView whenever you want to re-apply the filter, i.e. whenever your Login property is set to a new value. Something like this:

    public class DataFilters : ViewModelBase
    {
        private ICollectionView _UserMappedRolesView;
        public ICollectionView UserMappedRolesView
        {
            get { return _UserMappedRolesView; }
            set { _UserMappedRolesView = value; NotifyPropertyChanged(); }
        }
    
        private ObservableCollection<UserMappedRoles> _UserMappedRoles;
        public ObservableCollection<UserMappedRoles> UserMappedRoles
        {
            get
            {
                return _UserMappedRoles;
            }
            set
            {
                _UserMappedRoles = value;
                NotifyPropertyChanged();
                UserMappedRolesView = CollectionViewSource.GetDefaultView(_UserMappedRoles);
                UserMappedRolesView.Filter = UserMappedRolesFilter;
                UserMappedRolesView.Refresh();
            }
        }
    
        public void LoadUserMappedRoles()
        {
            var baseData = InformedWorkerBusinessService.UserMappedRoles.Get();
            var modelData =
                from data in baseData
                select new UserMappedRoles
                {
                    Enabled = 1,
                    Login = data.Login,
                    UserMappedRolesRef = data.UserMappedRolesRef,
                    UserRoleRef = data.UserRoleRef
    
                };
            UserMappedRoles = new ObservableCollection<UserMappedRoles>(modelData);
        }
    
    
        private string _login;
        public string Login
        {
            get { return _login; }
            set { _login = value; _UserMappedRolesView.Refresh(); }
        }
    
    
        private bool UserMappedRolesFilter(object item)
        {
            UserMappedRoles UserMappedRole = item as UserMappedRoles;
            if (UserMappedRole.Login == Login)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }