Как использовать CollectionViewSource для фильтрации ObservableCollection <T>, отображаемой в ListView - PullRequest
0 голосов
/ 02 апреля 2020

Я видел много похожих вопросов, но мне не удалось найти ни вопрос / ответ, ни учебник, в котором четко перечислены все компоненты, необходимые для его работы. Я пытаюсь следовать MVVM, но, поскольку это полностью связано с пользовательским интерфейсом, я не против создания некоторого кода.

Чего я пытаюсь достичь:

  • ListView.ItemsSource привязан к ObservableCollection<T>
  • Фильтр отображаемых элементов в ListView на основе TextBox
  • Фильтр обновляется как пользовательские типы в TextBox

В моем ViewModel у меня есть что-то вроде этого:

private ObservableCollection<Customer> _customers;
public ObservableCollection<Customer> Customers
{
    get { return _customers; }
    set
    {
        _customers= value;
        RaisePropertyChanged("Customers");
    }
}

private Customer _selected_Customer;
public Customer Selected_Customer
{
    get { return _selected_Customer; }
    set
    {
        _selected_Customer= value;
        RaisePropertyChanged("Selected_Customer");
    }
}

private string _filtered_Name;
public string Filtered_Name
{
    get { return _filtered_Name; }
    set
    {
        _filtered_Name = value;
        RaisePropertyChanged("Filtered_Name");
    }
}

И в моем XAML это выглядит так:

<CollectionViewSource x:Key="cvs"
                      x:Name="Customer_Details_View"
                      Source="{Binding Path=Customers}"/>

<TextBox x:Name="Filtered_Name" Text="{Binding Filtered_Name, Mode=TwoWay}"/>

<ListView ItemsSource="{Binding ElementName=Customer_Details_View}"
          SelectedItem="{Binding Selected_Customer, Mode=TwoWay}">

Я хочу отфильтровать свой ObservableCollection<Customer> с помощью следующего logi c: Customer.Name.ToLower().Contains(Filtered_Name.ToLower())

Как связать TextBox.Text с CollectionViewSource или использовать событие CollectionViewSource.Filter для применения вышеуказанного фильтра?

1 Ответ

0 голосов
/ 02 апреля 2020

Вы, вероятно, захотите объявить источник collectionview в вашей виртуальной машине и связать его напрямую Как только вы это сделаете, вы можете изменить фильтр, как ответили в этом вопросе CollectionViewSource, как фильтровать данные?

Пример виртуальной машины может не работать без массажа.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;

namespace CollectionViewSourceExample
{
    class MainWindowViewModel : INotifyPropertyChanged
    {
        private string _filter;

        public MainWindowViewModel()
        {
            SourceCollection = new ObservableCollection<string>();
            SourceCollection.Add("Fred Flintstone");
            SourceCollection.Add("Wilma Flintstone");
            SourceCollection.Add("Bambam Flintstone");
            SourceCollection.Add("Barny Rubble");
            SourceCollection.Add("Betty Rubble");

            ViewSource = (ListCollectionView)CollectionViewSource.GetDefaultView(SourceCollection);
            ViewSource.Filter = SourceFilter;
            ViewSource.IsLiveFiltering = true;
        }

        private bool SourceFilter(object obj)
        {
            string val = (string)obj;
            return string.IsNullOrWhiteSpace(Filter) || val.Contains(Filter);
        }

        public string Filter
        {
            get { return _filter; }
            set
            {
                _filter = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Filter"));
                ViewSource.Refresh();
            }
        }

        public ObservableCollection<string> SourceCollection { get; }
        public ListCollectionView ViewSource { get; }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...