Отображение отсортированной коллекции ObservableCollection в ListView и ее обновление при изменении базового DBSet

У меня есть ObservableCollection из Film называется Films в моем FilmListViewModel который я затем отображаю так:

<ListView Grid.Row="0" ItemsSource="{Binding FilmListViewModel.Films }">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name" Width="Auto" DisplayMemberBinding="{Binding Name}" />
            <GridViewColumn Header="Genre" Width="Auto" DisplayMemberBinding="{Binding Genre}" />
        </GridView>
    </ListView.View>
</ListView>

Items это свойство, и его получатель выглядит так:

public ObservableCollection<Film> Films
{
    get { return this._DBcontext.Set<Film>().Local; }
}

Когда я удаляю фильм из коллекции предметов, список фильмов в окне автоматически обновляется и укорачивается. Тем не менее, я хочу сделать другие операции в списке фильмов: сортировка, фильтрация и поиск. Поэтому я добавил еще одно свойство к FilmListViewModel называется OrderedFilms, который:

public ObservableCollection<Film> OrderedFilms
{
    get 
    {
        orderedFilms = this._DBcontext.Set<Film>().Local.OrderBy(film => film.Name);
        return new ObservableCollection<Film> (orderedFilms);
    }
 }

В thew ListView я меняю ItemsSource в

ItemsSource="{Binding FilmListViewModel.OrderedFilms }"

Тем не менее, если я затем удаляю пленку из базовой таблицы в _DBContext список фильмов в окне не обновляется. Я подозреваю, что причина в том, что получатель OrderedFilms на самом деле строит новый ObservableCollection и возвращает это.

Как я могу отобразить базовую таблицу Films в измененном виде (отфильтрован, отсортирован и т. Д.) И по-прежнему корректно обновлять ее в окне при изменении таблицы?

1 ответ

Решение

ObservableCollection<T> класс - не более чем реализация списка с уведомлениями об изменениях (INotifyCollectionChanged а также INotifyPropertyChanged). Важно то, что он имеет семантику хранения, поэтому даже конструкторы, которые принимают IEnumerable<T> или же List<T> просто создайте копию (снимок) из переданной коллекции.

Так что пока ваш Films свойство является средством доступа к реальному наблюдаемому хранилищу, наблюдаемая коллекция возвращается OrderedFilms является отключенным упорядоченным / отфильтрованным снимком хранилища.

Что вам действительно нужно, так это класс, предоставляющий представление (отсортированное, отфильтрованное) хранилища, сохраняющее ссылку на него и реагирующее на уведомления об изменении источника. К счастью, WPF предоставляет такой класс из коробки, который называется CollectionView

Представляет представление для группировки, сортировки, фильтрации и навигации по сбору данных.

Ты можешь использовать CollectionViewSource.GetDefaultView метод для получения реализации представления коллекции для вашего Films свойство, а затем фильтровать, сортировать и привязывать к этому представлению.

Вы можете найти больше информации о CollectionView а также CollectionViewSource в документации MSDN, а также в этих полезных ссылках. Навигация, группировка, сортировка и фильтрация данных в WPF, работа с CollectionView в WPF(фильтр, сортировка, группировка, навигация) и т. д.

Другие вопросы по тегам