1. 程式人生 > >談談WPF中的CollectionView與CollectionViewSource (1)

談談WPF中的CollectionView與CollectionViewSource (1)

pan 列表控件 add wpf win 之間 數據 n) style

原文:談談WPF中的CollectionView與CollectionViewSource (1)

談談WPF中的CollectionView與CollectionViewSource (1)
周銀輝

1,CollectionView
是什麽?
事實上當你將後臺數據列表綁定到一個列表控件時,WPF為了默默地在數據列表和列表控件之間增加了層稱為CollectionView(列表視圖)的東西,其支持很多高級操作,比如排序,分組,過濾等.這樣我們就可以將這個過程分成3個部分來看:數據列表(維持著後臺數據),列表視圖(維持著一些附加狀態,比如"當前項","排序"等),列表控件(負責對CollectionView的呈現,而不是對Collection)
CollectionView是針對數據的,但它不會改變數據,僅僅是對數據的"映像"進行"排列組合排序"等等.一組數據可以有若幹個CollectionView,就像可以對一個人拍攝若幹DV一樣.所以針對後臺給我們的一組數據我們可以同時為用戶提供若幹種展現方式.
列表控件(比如ListBox)可以針對數據,也可以針對CollectionView,比如我們可以手動地向其Items集合中添加數據,也可以用ItemsSource來指定數據來源,前者是針對數據本身,這需要我們來手動維護數據的和控件之間的關系.後者是針對CollectionView,如果你沒有指定列表控件對應的CollectionView,那麽WPF會自動插入一個.(需要註意的是:由於同時指定Items和ItemsSource會造成混亂,所以不可以同時操作他們)
比如:<ListBox ItemsSource="{Binding Source={StaticResource myList}}"/>
或者:

技術分享圖片CollectionView cv = new CollectionView(myList);
技術分享圖片
this.listBox.ItemsSource = cv;
2,CollectionViewSource是什麽?
CollectionViewSource是CollectionView的一個XAML代理,意思就是說CollectionView不能在XAML中使用,如果希望在XML將CollectionView綁定到某個列表控件,那麽請使用CollectionViewSource.它與CollectionView的基本關系是"HAS A". CollectionViewSource擁有一個CollectionView類型的View屬性來指定其對應的CollectionView對象,與之對應的,其還有一個Source屬性,來指明數據來源.一個簡單的流程是:將數據列表綁定到CollectionViewSource的Source屬性,然後將列表控件的ItemsSource屬性綁定到CollectionViewSource的View屬性.為什麽不直接將列表控件的ItemSource屬性綁定到數據列表呢,這取決於你是否需要查找到該CollectionViewSource進而查找到其View來進行視圖操作(比如排序,導航等).這可能說得有些混亂了.看看下面的例子:
技術分享圖片
<Window.Resources>
技術分享圖片
技術分享圖片
<XmlDataProvider x:Key="Employees" XPath="/Employees/*">
技術分享圖片
<x:XData>
技術分享圖片
<Employees xmlns="">
技術分享圖片
<Employee Name="Terry Adams" Type="FTE" EmployeeNumber="1" />
技術分享圖片
<Employee Name
="Claire O&apos;Donnell" Type="FTE" EmployeeNumber="12345" />
技術分享圖片
<Employee Name="Palle Peterson" Type="FTE" EmployeeNumber="5678" />
技術分享圖片
<Employee Name="Amy E. Alberts" Type="CSG" EmployeeNumber="99222" />
技術分享圖片
<Employee Name="Stefan Hesse" Type="Vendor" EmployeeNumber="-" />
技術分享圖片
</Employees>
技術分享圖片
</x:XData>
技術分享圖片
</XmlDataProvider>
技術分享圖片
技術分享圖片
<DataTemplate DataType="Employee">
技術分享圖片
<TextBlock Text="{Binding [email protected]}" />
技術分享圖片
</DataTemplate>
技術分享圖片
技術分享圖片
</Window.Resources>
技術分享圖片
技術分享圖片
<StackPanel>
技術分享圖片
<ListBox ItemsSource="{Binding Source={StaticResource Employees}}"/>
技術分享圖片
</StackPanel> 上面的例子中,我們按照傳統的方式,將ListBox的ItemsSource綁定到一個XMLDataProvider上,工作得很好,後來我們發現WPF中可以利用CollectionView來實現列表排序,當然這種排序我們希望僅僅是在表現層,所以我們決定我XAML來做.當在實際改造這段代碼的過程中,我們傷透了腦子,因為要在XAML中為我們的數據找到CollectionView對象並非易事.
事實上,我們僅僅需要改變一下數據綁定的流程就可以了.我們將數據與CollectionViewSource關聯,然後CollectionViewSource與列表控件相關聯,然後我們就可以在CollectionViewSource插入我們任何想要的排序方式了.
技術分享圖片 <Window.Resources>
技術分享圖片
技術分享圖片
<XmlDataProvider x:Key="Employees" XPath="/Employees/*">
技術分享圖片
<x:XData>
技術分享圖片
<Employees xmlns="">
技術分享圖片
<Employee Name="Terry Adams" Type="FTE" EmployeeNumber="1" />
技術分享圖片
<Employee Name="Claire O&apos;Donnell" Type="FTE" EmployeeNumber="12345" />
技術分享圖片
<Employee Name="Palle Peterson" Type="FTE" EmployeeNumber="5678" />
技術分享圖片
<Employee Name="Amy E. Alberts" Type="CSG" EmployeeNumber="99222" />
技術分享圖片
<Employee Name="Stefan Hesse" Type="Vendor" EmployeeNumber="-" />
技術分享圖片
</Employees>
技術分享圖片
</x:XData>
技術分享圖片
</XmlDataProvider>
技術分享圖片
技術分享圖片
<CollectionViewSource x:Key="cvs" Source="{Binding Source={StaticResource Employees}, XPath=/Employees/*}">
技術分享圖片
<CollectionViewSource.SortDescriptions>
技術分享圖片
<!--在這裏插入排序描述-->
技術分享圖片
</CollectionViewSource.SortDescriptions>
技術分享圖片
<CollectionViewSource.GroupDescriptions>
技術分享圖片
<!--在這裏插入分組描述-->
技術分享圖片
</CollectionViewSource.GroupDescriptions>
技術分享圖片
</CollectionViewSource>
技術分享圖片
技術分享圖片
<DataTemplate DataType="Employee">
技術分享圖片
<TextBlock Text="{Binding [email protected]}" />
技術分享圖片
</DataTemplate>
技術分享圖片
技術分享圖片
</Window.Resources>
技術分享圖片
技術分享圖片
<StackPanel>
技術分享圖片
<ListBox ItemsSource="{Binding Source={StaticResource cvs}}" x:Name="lb"/>
技術分享圖片
</StackPanel>

談談WPF中的CollectionView與CollectionViewSource (1)