Một collection cũng có thể được coi là một đối tượng, tuy nhiên việc binding loại dữ liệu này yêu cầu những chức năng như sắp xếp, lọc, gom nhóm,… Trong bài này, tôi sẽ giới thiệu về Collection View và sử dụng để thực hiện các chức năng này trên dữ liệu được binding vào ListBox.
Collection View là gì?Đây là một lớp dùng để hiển thị dữ liệu và cung cấp các chức năng duyệt, sắp xếp, lọc,… trên một collection. Việc sử dụng các chức năng này không ảnh hưởng gì đến dữ liệu nguồn. Với những thao tác làm thay đổi dữ liệu nguồn như thêm, xóa,… collection cần được hiện thực interface INotifyCollectionChanged. Tuy nhiên WPF cũng cung cấp một lớp generic là ObservableCollection<T> đã được hiện thực sẵn INotifyCollectionChanged để bạn sử dụng mà không cần tạo thêm một kiểu collection mới. Thay vì tạo một đối tượng mới, bạn cũng có thể lấy Collection View mặc định của một collection bằng phương thức static CollectionViewSource.GetDefaultView() với kiểu trả về là System.ComponentModel.ICollectionView. Tạo Collection ViewTôi có một lớp Person sau:
public class Person { public int Age{get;set;} public string Name {get;set;} public override string ToString() { return string.Format("{0} - age: {1}",Name,Age); } }
và một lớp Window1 với property Persons:
public partial class Window1 : Window { ObservableCollection<Person> _persons =new ObservableCollection<Person>(){ new Person(){Age=10,Name="John"}, new Person(){Age=11,Name="Alice"}, new Person(){Age=12,Name="Danby"}, }; ... public ObservableCollection<Person> Persons{ get { return _persons; } } }
Để tạo một Collection View trong XAML, bạn cần sử dụng lớp CollectionViewSource, đây là lớp đại diện cho CollectionView. Sử dụng property Source để xác định dữ liệu nguồn:
<Window x:Name="mainWindow" x:Class="BindingExample.Window1" ... > <Window.Resources> <CollectionViewSource Source="{Binding ElementName=mainWindow, Path=Persons}" x:Key="myCollectionView" /> </Window.Resources> ... </Window>
Sau đó bạn có thể dùng CollectionViewSource này làm binding source cho một control hiển thị collection như ListBox:
<ListBox x:Name="listBox1" ItemsSource="{Binding Source={StaticResource myCollectionView}}"/>
Thay vì dùng XAML, bạn có thể viết trong code-behind:
CollectionView collectionView=new CollectionView(this.Persons); listBox1.ItemsSource = collectionView; // or ICollectionView collectionView = CollectionViewSource.GetDefaultView(Persons); listBox1.ItemsSource=collectionView;
SortingCollection View chứa một collection SortDescriptions các đối tượng SortDescription. Mỗi SortDescription tương ứng với một cột (property của phần tử trong collection) cần xếp thông qua hai property là PropertyName và Direction. Ví dụ sau thực hiện sắp xếp giảm dần theo property Name của collection:
<Window x:Name="mainWindow" x:Class="BindingExample.Window1" ... xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"> <Window.Resources> <CollectionViewSource Source="{Binding ElementName=mainWindow, Path=Persons}" x:Key="myCollectionView" > <CollectionViewSource.SortDescriptions> <scm:SortDescription PropertyName="Name" Direction="Descending" /> </CollectionViewSource.SortDescriptions> </CollectionViewSource> </Window.Resources> ... </Window>
Trong code-behind:
ICollectionView collectionView = CollectionViewSource.GetDefaultView(Persons); collectionView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Descending)); listBox1.ItemsSource=collectionView; // or listBox1.Items.SortDescriptions.Add(new SortDescription("Name",ListSortDirection.Descending));
FilteringCollection View cung cấp một property Filter có kiểu Predicate<Object>. Kiểu này là một delegate chấp nhận một tham số kiểu object và trả về một giá trị boolean dựa trên các điều kiện bạn thực hiện trên tham số đó. Ví dụ nếu muốn lọc ra các Person có Age > 10. Ta có thể viết:
listBox1.Items.Filter=(obj)=> ((Person)obj).Age>10;
GroupingViệc gom nhóm dữ liệu trong collection để hiển thị trên ListBox cần phải thiết lập giá trị property ItemsControl.GroupStyle. Thay vì tạo một custom GroupStyle, bạn có thể dùng giá trị mặc định GroupStyle.Default để hiển thị:
<ListBox x:Name="listBox1" ItemsSource="{Binding}"> <ListBox.GroupStyle> <x:Static Member="GroupStyle.Default" /> </ListBox.GroupStyle> </ListBox>
Để gom nhóm theo một property, bạn cần tạo một đối tượng PropertyGroupDescription và gán giá trị cho property PropertyName. Ví dụ tôi muốn gom nhóm theo property Age của Person:
PropertyGroupDescription groupDescription = new PropertyGroupDescription(); groupDescription.PropertyName = "Age"; listBox1.Items.GroupDescriptions.Add(groupDescription);
Với dữ liệu cần hiển thị là:
ObservableCollection<Person> _persons =new ObservableCollection<Person>(){ new Person(){Age=10,Name="John"}, new Person(){Age=11,Name="Alice"}, new Person(){Age=12,Name="Danby"}, new Person(){Age=12,Name="Tobin"}, };
Sử dụng custom GroupStyle, bạn có thể tạo một DataTemplate để thiết lập kiểu hiển thị của phần tiêu đề mỗi nhóm. Như ví dụ sau:
<Window x:Name="mainWindow" x:Class="BindingExample.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" Title="BindingExample" Height="300" Width="300" > <Window.Resources> <CollectionViewSource Source="{Binding ElementName=mainWindow, Path=Persons}" x:Key="myCollectionView" /> <DataTemplate x:Key="groupTemplate" DataType="Group"> <Border Margin="4" BorderBrush="Blue" BorderThickness="1" > <StackPanel Orientation="Horizontal" Background="DarkGray"> <TextBlock Text="Group: " Foreground="LightCyan"/> <TextBlock Text="{Binding Name}" Foreground="White"/> </StackPanel> </Border> </DataTemplate> </Window.Resources> <StackPanel DataContext="{StaticResource myCollectionView}"> <ListBox x:Name="listBox1" ItemsSource="{Binding}"> <ListBox.GroupStyle> <GroupStyle HeaderTemplate="{StaticResource groupTemplate}"/> </ListBox.GroupStyle> </ListBox> </StackPanel> </Window>
Kết quả: Binding đến phần tử hiện tại trong Collection ViewXAML sử dụng kí tự “/” dùng cho việc binding đến phần tử hiện tại trong Collection View. Mỗi dấu “/” tương ứng với một cấp của collection. Bạn có thể coi đây giống như dấu ngăn cách tên các thư mục trong Windows Explorer. Ví dụ này tôi gán dữ liệu dạng collection cho DataContext của một phần tử cha của các Label, sau đó binding đến collection và phần tử hiện tại trong Collection View vào property Label.Content:
<Label Content="{Binding}" /> <!-- collection --> <Label Content="{Binding Path=/}" /> <!-- current item --> <Label Content="{Binding Path=/Name}" /> <!-- Name property of current item --> <Label Content="{Binding Path=/Name/}" /> <!-- First charater of Name property (a string is a collection of character) -->
Screenshot: Mã nguồn hoàn chỉnh của tài liệu Window1.xaml:
<Window x:Name="mainWindow" x:Class="BindingExample.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" Title="BindingExample" Height="300" Width="300" > <Window.Resources> <CollectionViewSource Source="{Binding ElementName=mainWindow, Path=Persons}" x:Key="myCollectionView" > <CollectionViewSource.SortDescriptions> <scm:SortDescription PropertyName="Name" Direction="Descending" /> </CollectionViewSource.SortDescriptions> </CollectionViewSource> </Window.Resources> <StackPanel DataContext="{StaticResource myCollectionView}"> <ListBox x:Name="listBox1" ItemsSource="{Binding}"/> <Label Content="{Binding}" /> <!-- collection --> <Label Content="{Binding Path=/}" /> <!-- current item --> <Label Content="{Binding Path=/Name}" /> <!-- Name property of current item --> <Label Content="{Binding Path=/Name/}" /> <!-- First charater of Name property (a string is a collection of character) --> </StackPanel> </Window>
http://yinyangit.wordpress.com Related articles |
WPF – Data Binding và Collection: Sorting, Filtering, Grouping
Ý kiến bạn đọc
Tin tức khác
WPF – Giới thiệu về Animation
- 6/8/2012
WCF – Self-hosted Service đơn giản
- 13/4/2012
WCF – Một số khái niệm cơ bản
- 10/4/2012
WPF – Tùy biến TabControl
- 28/3/2012
WPF – Tìm hiểu về ContentPresenter
- 28/3/2012
WPF – 2D Matrix Transformation
- 28/3/2012
WPF – 2D Transformations
- 28/3/2012
WPF – Multi Language với Binding và ResourceDictionary
- 28/3/2012
WPF – Sử dụng Resource Dictionary
- 26/3/2012
WPF – Tạo Custom Validation Rule
- 26/3/2012
Tin tiêu điểm
-
WPF – Control Template (171,525)
-
WPF – Data Validation (124,624)
-
WPF – Tùy biến TabControl (92,027)
-
WPF – Data Binding và Collection: Sorting, Filtering, Grouping (26,356)
-
WPF – Read-Only Attached Dependency Property (19,620)
-
WPF – Multi Language với Binding và ResourceDictionary (11,374)
-
WPF – Tạo Custom Validation Rule (9,965)
-
WPF – Data Binding cơ bản (9,769)
-
WPF – 2D Transformations (9,293)
-
WPF – Giới thiệu về Animation (8,229)
Gallery
Text Links
Thiết kế logo chuyên nghiệp Insky
DAFABET
W88 w88b.com/dang-ky-tai-khoan-w88
W88
ca do bong da online
DAFABET
W88 w88b.com/dang-ky-tai-khoan-w88
W88
ca do bong da online
Tags
asp.net
JavaScript
Lập trình
Cơ sở dữ liệu
jquery
Csharp
Ajax
Thủ thuật
JavaScript
menu
Sql Server
Lập trình C#
WebService
stty
Sql
Phân trang
Rewrite
Mã hoá
Backup
Thủ thuật lập trình
Store procedure
Accordion
Validation
Store
Upload
Slide
jQueryPlugin
StoreProcedure
Regular Expression
Regex
android
Quick and snow
HTML5
WPF
WCF
Copyright © 2011 - 2012 vietshare.vn
by
phamkhuong102@gmail.com doanhkisi2315@gmail.com. All rights reserved.