文章目錄
- CollectionView與CollectionViewSource
-
- ICollectionView
- CollectionViewSource
- 參考
CollectionView與CollectionViewSource
ICollectionView
- 允許集合具有目前記錄管理、自定義排序、篩選和分組這些功能。
- 當你将背景資料清單綁定到一個清單控件時,WPF為了默默地在資料清單和清單控件之間增加了層稱為CollectionView(清單視圖)的東西,其支援很多進階操作,比如排序,分組,過濾等.這樣我們就可以将這個過程分成3個部分來看:資料清單(維持着背景資料),清單視圖(維持着一些附加狀态,比如"目前項","排序"等),清單控件(負責對CollectionView的呈現,而不是對Collection)
- CollectionView是針對資料的,但它不會改變資料,僅僅是對資料的"映像"進行"排列組合排序"等等.一組資料可以有若幹個CollectionView,就像可以對一個人拍攝若幹DV一樣.是以針對背景給我們的一組資料我們可以同時為使用者提供若幹種展現方式.
- 清單控件(比如ListBox)可以針對資料,也可以針對CollectionView,比如我們可以手動地向其Items集合中添加資料,也可以用ItemsSource來指定資料來源,前者是針對資料本身,這需要我們來手動維護資料的和控件之間的關系.後者是針對CollectionView,如果你沒有指定清單控件對應的CollectionView,那麼WPF會自動插入一個.(需要注意的是:由于同時指定Items和ItemsSource會造成混亂,是以不可以同時操作他們)
- 比如:
- 或者:
CollectionView cv = new CollectionView(myList); this.listBox.ItemsSource = cv;
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'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'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)】