2013-08-31 2 views
2

Я новичок в WPF и, похоже, я тоже не понимаю C#.
Приведенный ниже код должен предоставлять отсортированные данные DataGrid.Переменная типа ICollectionView Тип интерфейса

Вот код, я изо всех сил, чтобы понять:

ObservableCollection<Person> PersonsCollection = new ObservableCollection<Person>(); 
//this one is easy: I create new collection for objects of class Person and I call it PersonsCollection 

ICollectionView PersonsView = CollectionViewSource.GetDefaultView(PersonsCollection); 
//this one is more complicated. Does it mean that I create new object called PersonsView which I assume that implements ICollectionView interface? 

ListCollectionView personsView = PersonsView as ListCollectionView; 
//this one I do not understand. Why do we need it? How can we treat PersonsView as ListCollectionView? 

personsView.CustomSort = new PersonSorter(); 
//here we assign object of PersonSorter class to do the sorting. Fine with me. 

dataGrid1.ItemsSource = personsView; 
//and here we assign personsView as a ItemsSource for our DataGrid. Fine with me. 

Любая помощь? Спасибо :-)

ответ

2

этот простой: я создаю новую коллекцию для объектов класса Person, и я называю это PersonCollection.

Правильно, но сначала я хотел прояснить некоторые вещи. Вы можете использовать любую коллекцию здесь, а точнее любую IEnumberable.

Что отличает ObservableCollection от нормального IEnumerable, так это то, что первый вызывает уведомления, когда элементы добавляются, удаляются или переупорядочиваются в коллекции, в то время как последний нет.

ВАЖНО: Одна вещь, чтобы заметить, что независимо от того, какой тип коллекции, IEnumberable или ObservableCollection, когда эта коллекция используется в привязках, то система WPF создает ли обертку вокруг этой коллекции (источник) , вроде как по умолчанию вид.

Этот вид реализует ICollectionView. Он сохраняет понятие текущего элемента и предоставляет такие возможности, как сортировка, навигация, фильтрация и группировка.

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

Мне пришлось очистить эту последнюю важную тему, потому что она касается вопросов впереди.

этот сложнее. Означает ли это, что я создаю новый объект под названием PersonView, который, как я предполагаю, реализует интерфейс ICollectionView?

Нет или, по крайней мере, не совсем так. Вы получаете ссылку на это представление по умолчанию, которое будет создано системой WPF, поэтому метод получения этого объекта называется GetDefaultView(), а не что-то вроде CreateDefaultView().

этот один не понимаю. Зачем нам это нужно? Как мы можем рассматривать PersonView как ListCollectionView?

Нам это действительно не нужно, мы можем идти без этой линии. Мы можем рассматривать PersonView как ListCollectionView, так как

все коллекции имеют коллекцию CollectionView по умолчанию. Для всех коллекций , реализующих IList, объект ListCollectionView является объектом по умолчанию .

MSDN Documentation.

Остальная часть - это штраф с вами и штраф от меня, поэтому не нужно комментировать.

1

ObservableCollection Вы создаете ObservableCollection, который используется для запуска события CollectionChanged, это изменение значения DP.
ICollectionView вы создаете вид из коллекции человека, который будет использоваться для отображения данных коллекции в WPF DataGrid и т.д.
ListCollectionView smilar к ICollectionView но вы можете сортировать или фильтрует Itmes т.д.

personsView.CustomSort = new PersonSorter(); // depending on which Tech you are using for example it might be you are creating the sorting property Name. 
2

Вот мой понимание:

Ваша первая линия:

ObservableCollection<Person> PersonsCollection = new ObservableCollection<Person>(); 

Как справедливо сказать, создает вашу наблюдаемую коллекцию Persons, вы можете напрямую связать эту коллекцию (технически я считаю, что вы привязываетесь к умолчанию CollectionView), и ваш DataGrid будет уведомлен об изменениях в коллекции и соответственно обновит их. Но вам нужна дополнительная функция сортировки данных.

Итак, ваша вторая линия:

ICollectionView PersonsView = CollectionViewSource.GetDefaultView(PersonsCollection); 

Является ли использование GetDefaultView для возврата по умолчанию CollectionView для вашего PersonsCollection, CollectionView является оболочкой вокруг существующей коллекции, которая даст вам дополнительные поведения, как фильтрация, группировка, навигационная и сортировка. Когда коллекция связана в WPF, привязка относится к объекту CollectionView, и именно эти представления обрабатываются при сортировке и отображении данных и т. Д.

Случается, что тип по умолчанию CollectionViewSource для этого типа, является ListCollectionView, но так как это может различаться в зависимости от того, какой тип объекта вы передаете CollectionViewSource.GetDefaultView(), метод возвращает интерфейс, ICollectionView.

Таким образом, в данный момент, мы могли бы использовать ICollectionView, PersonsView как ItemsSource, но мы хотим, чтобы определить пользовательские сортировки поведение, определяя CustomSort, который можно найти на ListCollectionView.

Поскольку мы знаем, что представление по умолчанию является ListCollectionView, мы можем явно привести ICollectionView объект соответственно (третья строка), а затем установите нужный сортировки поведение (4-я строка):

ListCollectionView personsView = PersonsView as ListCollectionView; 

personsView.CustomSort = new PersonSorter(); 

Надеюсь, некоторые более знающие пользователи укажут на любые ошибки, которые я сделал.

+0

ICollectionView разрешен для использования в ItemsSource? Но это интерфейс, а не сборник, и как он работает? –

+0

Вы не можете напрямую создать интерфейс, поэтому возвращаемый объект будет конкретным классом, который реализует 'ICollectionView', если вы запросите возвращаемый тип, вы увидите, что это' ListCollectionView'. «ICollectionView» наследует от «IEnumerable», поэтому этот тип должен реализовывать «IEnumerable».Если вы посмотрите на свойство 'ItemsSource', оно имеет тип' IEnumerable', поэтому вы можете с радостью связать с любым типом, который реализует 'ICollectionView' (поскольку это означает, что он должен реализовывать' IEnumerable'. – Chris