почему мой ObservableCollection не фильтрует

у меня есть настольное приложение WPF.

Я загружаю ObservableCollection со списком объектов.

Я использую объект ICollectionView, чтобы «обернуть» фильтр вокруг этого ObservableCollection.

Я устанавливаю фильтр и обновляю, но он не работает, поэтому:

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;
        }
    }
}

и мой тестовый скрипт:

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;

Я знаю, что мои данные содержат только oUserMappedRoles, где имя входа — «Энди», поэтому, установив имя фильтра входа в систему на «Дэвид», я ожидаю, что не вернут никаких записей.

Я установил точки останова везде, и каждая строка кода «срабатывает».

Я (очевидно) реализовал это неправильно?

Спасибо


person Andrew Simpson    schedule 23.12.2016    source источник
comment
Не очень хорошая практика изменять ObservableCollection, она действительно должна быть определена как коллекция только для чтения, которую вы можете очистить и обновить, но не заменить. Wpf не так хорошо обрабатывает изменения, когда список удаляется (также подумайте о возможных других событиях NotifyPropertyChanged, которые могут быть связаны с ним)   -  person Icepickle    schedule 23.12.2016
comment
@Icepickle Привет, спасибо за ваш комментарий. Но это то, что делает мой код. он загружает наблюдаемую коллекцию со всем только один раз, а затем я применяю к ней фильтры   -  person Andrew Simpson    schedule 23.12.2016


Ответы (1)


Фильтруется ICollectionView, а не ObservableCollection.

Итак, вы должны привязаться к свойству ICollectionView:

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

...или найдите отфильтрованные элементы в этом:

var filtered = VM.CommonData.DataFilters.UserMappedRolesView;

Вам также необходимо обновлять CollectionView всякий раз, когда вы хотите повторно применить фильтр, т. е. всякий раз, когда для вашего свойства Login установлено новое значение. Что-то вроде этого:

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;
        }
    }
}
person mm8    schedule 23.12.2016