Как сделать мой связанный WPF DataGrid сортируемым?

Мой WPF4 DataGrid привязан к несортированной коллекции - ObjectResult (of t). Я не могу понять, как вместо этого использовать сортируемую коллекцию, такую ​​как ListCollectionView.

Подробности. Когда приложение загружается, пользователь инициирует поиск, чтобы заполнить DataGrid и другие редактируемые элементы управления. Для выполнения поиска я создаю ObjectQuery (of t) на основе выбора фильтров пользователей. Метод Execute объекта ObjectQuery возвращает и ObjectResult, который я установил как свой CollectionViewSource.Source. В XAML DataGrid привязан к CollectionViewSource, который является DataContext для созданного мной экрана.

System.Data.Objects.ObjectQuery<LabSample> labSamplesQuery = this.GetLabSamplesFiltered_Query(_labEntitiesContext, sampleID_LIKE, xxx_LIKE, yyy_LIKE); 
System.Data.Objects.ObjectResult<LabSample> labSamples =  labSamplesQuery.Execute(System.Data.Objects.MergeOption.AppendOnly);
_labSamplesCollectionViewSource.Source = labSamples;      

Поскольку DataGrid привязан к ObjectResult (of t), его нельзя сортировать. Как мне получить результаты моего запроса (labSamples) в сортируемую и обновляемую коллекцию, прежде чем назначить ее источником моих данных (CollectionViewSource.Source)?


person DeveloperDan    schedule 31.01.2011    source источник
comment
Вам нужно, чтобы коллекция была обновляемой?   -  person Mark Rendle    schedule 31.01.2011
comment
да. Это похоже на такое базовое требование - пользователи ищут данные, а я выгружаю результаты в сетку, чтобы пользователи могли редактировать записи. Где есть веб-страница или видео, чтобы узнать, как это сделать? Я пометил ответ Аарона как принятый слишком рано. Его ответ дает мне сортируемую сетку с ICollectionView в качестве DataGrid.ItemsSource, но другие мои элементы управления больше не привязаны. Я хочу, чтобы DataContext моей формы соответствовал тому, что я использую для ItemSource DataGrid.   -  person DeveloperDan    schedule 31.01.2011


Ответы (2)


Вы можете обернуть свою коллекцию ICollectionView и вернуть ее в привязанный DataGrid.

    private ICollectionView _view;

    public ICollectionView Samples
    {
        get 
        {
            if (_view == null)
            {
                _view = CollectionViewSource.GetDefaultView(new ObservableCollection<LabSample>(labSamples));
                _view.SortDescriptions.Add(new SortDescription("PropertyName", ListSortDirection.Ascending));
            }

            return _view;
        }
    }

Вы также можете установить логику сортировки в XAML. У Би есть статья о достижении этого здесь. Если вы сделаете ObservableCollection<LabSamples> переменной уровня класса или содержащейся в службе, содержащей обернутую ссылку, ваши изменения будут отражены в DataGrid.

person Aaron McIver    schedule 31.01.2011
comment
Это ответ, который я искал в сети. Спасибо! Могу ли я назначить ICollectionView как мой _labSamplesCollectionViewSource.Source и использовать его как DataContext для всех редактируемых элементов управления? - person DeveloperDan; 31.01.2011
comment
В приведенном выше примере свойство Samples будет свойством объекта, которым будет ViewModel или DataContext для данного View. В вашем XAML вы можете напрямую связываться с Samples, поскольку базовая коллекция уже была обернута, когда мы вызывали GetDefaultView; попробуйте, так как этого должно хватить. Если вы хотите придерживаться использования явного CollectionViewSource, вам нужно будет назначить свой _labSamplesCollectionViewSource.Source недавно определенному ObservableCollection ‹LabSamples›, где ваш CollectionViewSource.View затем будет содержать ссылку на ICollectionView. - person Aaron McIver; 31.01.2011
comment
Вдобавок ICollectionView реализует IEnumerable, поэтому любые другие элементы управления, на которые вы ссылались и которые больше не привязаны, должны иметь возможность связываться, как и раньше. Можете ли вы обновить свой вопрос, включив в него информацию о других элементах управления? Если вам просто нужна коллекция с изменениями уведомлений, оберните свои результаты ... new ObservableCollection ‹LabSample› (labSamples) - person Aaron McIver; 31.01.2011
comment
Я сказал, что это ответ слишком быстро. Ответ, который вы дали, отлично работает, когда я устанавливаю DataGrid.ItemsSource на созданный _view. Но я не знаю, что теперь использовать в качестве DataContext для моих редактируемых элементов управления (мой вопрос чуть выше). Если кто-то знает хорошие ресурсы для создания базовой формы ввода данных WPF и EF, которая изначально заполняется фильтром пользователей, пожалуйста, дайте мне знать. Фильтр / поиск могут стать сложными, поэтому я надеюсь использовать составной LINQ ObjectQuery (из t). - person DeveloperDan; 31.01.2011
comment
@DeveloperDan Что вы использовали раньше в качестве DataContext? - person Aaron McIver; 31.01.2011
comment
Мой исходный DataContext был создан в XAML путем перетаскивания таблицы из окна источников данных (CollectionViewSource). Я еще не окончил мир ViewModels. Для меня важно закодировать это как свойство? Я попытался добавить ваш код в строку после моего labSamplesQuery.Execute. Я остановился на вашей строке SortDescriptors и попытался просто добавить вашу строку GetDefaultView. Возвращенным объектом является ListCollectionView, а не ICollectionView. Из-за этого я получаю сообщение об ошибке, когда назначаю ListCollectionView (_view) моему _labSamplesCollectionViewSource.Source. Итак, я все еще борюсь. - person DeveloperDan; 31.01.2011
comment
@DeveloperDan ListCollectionview наследует CollectionView, который реализует ICollectionView. В идеале использование ViewModel упростит вам жизнь в будущем. Однако, если вы установите для _labSamplesCollectionViewSource.Source значение ObservableCollection ‹LabSample› (labSamples), тогда _labSamplesCollectionViewSource.View будет связанным представлением для коллекции резервных копий. Это должно позволить вам использовать предопределенный ресурс в XAML, если это ваша цель. - person Aaron McIver; 31.01.2011
comment
Наконец-то работает! И мне нужно было изменить только одну строку в моем исходном коде. Последнюю строку я изменил на _labSamplesCollectionViewSource.Source = new System.Collections.ObjectModel.ObservableCollection ‹LabSample› (labSamples); - person DeveloperDan; 31.01.2011
comment
Это то, что вы говорили мне делать все время, но я не понимал концепции обертывания результатов в .... Спасибо за вашу настойчивость в помощи мне. Я считаю, что другим разработчикам, вроде меня, которые работали с Windows Forms с помощью ADO.Net, нужен лучший ресурс для изучения WPF CRUD. То, что я нашел, не соответствует стандартам. Аарон. Мне любопытно, как ты этому научишься? Еще раз спасибо! - person DeveloperDan; 31.01.2011
comment
@DeveloperDan Конечно, рад, что смог помочь. Лучший способ научиться - погрузиться в нее. Вот как я со временем подобрал его ... есть сообщение SO, в котором говорится о дополнительных ресурсах ... stackoverflow.com/questions/1526150/ - person Aaron McIver; 31.01.2011

WPF DataGrid нельзя будет отсортировать из-за отложенной загрузки. Вам необходимо использовать метод ToList () следующим образом: ..... _labSamplesCollectionViewSource.Source = labSamples.ToList (); Теперь сетка данных должна быть сортированной.

person Blerton Hoxha    schedule 17.05.2012