2

我是 WPF 新手,看起来我也不完全了解 C#。
下面的代码应该为 DataGrid 提供排序数据。

这是我难以理解的代码:

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.

有什么帮助吗?谢谢 :-)

4

3 回答 3

2

这个很简单:我为 Person 类的对象创建了新集合,我称之为 PersonsCollection。

正确,但我想先澄清一些事情。您可以在此处使用任何集合,或者更准确地说,任何IEnumberable.

anObservableCollection与普通的不同IEnumerable之处在于,第一个在集合中添加、删除或重新排序项目时会发出通知,而后者则不会。

重要提示:需要注意的一点是,无论是什么类型的集合,无论是 anIEnumberable还是 an ObservableCollection,当该集合用于绑定时,WPF 系统都会围绕该集合(源)创建一个包装器,有点像默认视图

该视图实现ICollectionView。它保留当前项目的概念,并提供排序、导航、过滤和分组等功能。

此视图与集合(源)相关,因此如果您有多个绑定到同一个集合,那么所有这些绑定实际上都绑定到 WPF 系统创建的默认视图,因此在更新默认视图时它们会一起更新。

我必须弄清楚最后一个重要的话题,因为它与前面的问题有关。

这个比较复杂。这是否意味着我创建了名为 PersonsView 的新对象,我假设它实现了ICollectionView接口?

没有或至少不完全正确。您将获得对将由 WPF 系统创建的默认视图的引用,这就是为什么调用获取该对象的方法GetDefaultView()而不是类似CreateDefaultView().

这个我不明白。为什么我们需要它?我们如何将 PersonsView 视为 ListCollectionView?

我们真的不需要它,我们可以不用这条线。我们可以将PersonView其视为ListCollectionView因为

所有集合都有一个默认的 CollectionView。对于所有实现 IList 的集合,ListCollectionView 对象是默认视图对象。

MSDN 文档

其余的对你来说很好,对我来说很好,所以不需要评论。

于 2013-08-31T22:25:10.937 回答
2

以下是我的理解:

你的第一行:

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

正如您正确地说,正在创建您的可观察集合Persons,您可以直接绑定到此集合(从技术上讲,我相信您绑定到默认值CollectionView),并且您DataGrid会收到有关集合更改的通知,并相应地更新。但是您需要对数据进行排序的附加功能。

所以,你的第二行:

ICollectionView PersonsView = CollectionViewSource.GetDefaultView(PersonsCollection);

使用GetDefaultView来返回默认值CollectionViewPersonsCollectionaCollectionView是现有集合的包装器,它将为您提供额外的行为,例如过滤、分组、导航和排序。当一个集合在 WPF 中绑定时,绑定到一个CollectionView对象,当数据被排序和显示等时,正是这些视图被操作。

碰巧CollectionViewSource这种类型的默认类型是 a ListCollectionView,但是由于这可能会根据您传递给的对象类型而有所不同CollectionViewSource.GetDefaultView(),因此该方法返回一个接口ICollectionView.

所以此时,我们可以使用ICollectionView,PersonsView作为ItemsSource,但我们想通过定义 a 来定义自定义排序行为,CustomSort它可以在 a 上找到ListCollectionView

由于我们知道默认视图是 a ListCollectionView,因此我们可以ICollectionView相应地显式转换对象(第 3 行),然后设置所需的排序行为(第 4 行):

ListCollectionView personsView = PersonsView as ListCollectionView;  

personsView.CustomSort = new PersonSorter();

希望一些更有知识的用户会指出我犯的任何错误。

于 2013-08-31T22:19:36.353 回答
1

ObservableCollection 您正在创建一个 ObservableCollection,它用于触发 CollectionChanged 事件,即更改 DP 值。
ICollectionView 您正在从人员集合创建视图,该视图将用于在 WPF 数据网格等中显示集合数据。
ListCollectionview 与 ICollectionView 类似,但您可以对项目等进行排序或过滤。

 personsView.CustomSort = new PersonSorter();  // depending on which Tech you are using for example it might be you are creating the sorting property Name.
于 2013-08-31T21:27:35.090 回答