[转]WPF and Silverlight 学习笔记(二十五):使用CollectionView实现对绑定数据的排序、筛选、分组
在第二十三节,我们使用CollectionView实现了对于绑定数据的导航,除导航功能外,还可以通过CollectionView对数据进行类似于DataView的排序、筛选等功能。
一、数据的排序:
使用第二十四节的数据源,查询所有的产品信息:
1: <Window x:Class="WPF_24.CollectionViewSortData"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:lib="clr-namespace:WPF_24_Library;assembly=WPF_24_Library"
5: Title="CollectionViewSortData" Height="300" Width="500">
6: <Window.Resources>
7: <ObjectDataProvider x:Key="myDataSource"
8: ObjectType="{x:Type lib:DataControl}"
9: MethodName="GetAllProductInfo" />
10: </Window.Resources>
11: <Grid Margin="5">
12: <Grid.RowDefinitions>
13: <RowDefinition />
14: <RowDefinition Height="50" />
15: </Grid.RowDefinitions>
16: <ListBox Grid.Row="0"
17: DataContext="{StaticResource myDataSource}"
18: ItemsSource="{Binding}">
19: <ListBox.ItemTemplate>
20: <DataTemplate>
21: <WrapPanel>
22: <TextBlock Text="{Binding Path=ProductID}" Width="50" />
23: <TextBlock Text="{Binding Path=ProductName}" Width="300" />
24: <TextBlock Text="{Binding Path=UnitPrice}" Width="50" />
25: </WrapPanel>
26: </DataTemplate>
27: </ListBox.ItemTemplate>
28: </ListBox>
29: <WrapPanel Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center">
30: <TextBlock Text="第一排序:" VerticalAlignment="Center" />
31: <ComboBox SelectedIndex="0" Width="80" x:Name="cmbColumnA">
32: <ComboBox.Items>
33: <ComboBoxItem Tag="ProductID">产品编号</ComboBoxItem>
34: <ComboBoxItem Tag="ProductName">产品名称</ComboBoxItem>
35: <ComboBoxItem Tag="UnitPrice">产品单价</ComboBoxItem>
36: </ComboBox.Items>
37: </ComboBox>
38: <TextBlock Text="第二排序:" VerticalAlignment="Center" />
39: <ComboBox SelectedIndex="0" Width="80" x:Name="cmbColumnB">
40: <ComboBox.Items>
41: <ComboBoxItem Tag="ProductID">产品编号</ComboBoxItem>
42: <ComboBoxItem Tag="ProductName">产品名称</ComboBoxItem>
43: <ComboBoxItem Tag="UnitPrice">产品单价</ComboBoxItem>
44: </ComboBox.Items>
45: </ComboBox>
46: <Button Content="排序" Margin="10,0,0,0" Click="Button_Click" />
47: </WrapPanel>
48: </Grid>
49: </Window>
实现对数据的排序,使用的是CollectionView对象中的SortDescriptions集合属性,其包含多个SortDescription对象,按照其先后顺序对数据实现排序。注意SortDescription对象的构造方法的两个参数,第一个参数是字符串类型的,表示数据类型中的某个属性的属性名,其属性的类型必须实现IComparable接口,即实现相应的排序规则;第二参数是ListSortDeirection枚举,表示排序的顺序是正序还遇倒序。
本例应在按钮的Click事件中定义如下的代码:
1: private void Button_Click(object sender, RoutedEventArgs e)
2: {
3: // 获取数据源适配器
4: ObjectDataProvider provider =
5: (ObjectDataProvider) (this.FindResource("myDataSource"));
6: // 获取数据源
7: List<ProductInfo> collections = (List<ProductInfo>) (provider.Data);
8:
9: // 获取数据源对应的CollectionView
10: ICollectionView view = CollectionViewSource.GetDefaultView(collections);
11: // 清除原有的排序
12: view.SortDescriptions.Clear();
13:
14: // 获取要排序的两个列的列名
15: string firstColumn = ((ComboBoxItem) (cmbColumnA.SelectedItem)).Tag.ToString();
16: string secendColumn = ((ComboBoxItem)(cmbColumnB.SelectedItem)).Tag.ToString();
17:
18: if (view.CanSort)
19: {
20: // 添加排序规则(注意添加的顺序)
21: view.SortDescriptions.Add(
22: new SortDescription(firstColumn,ListSortDirection.Ascending));
23: view.SortDescriptions.Add(
24: new SortDescription(secendColumn, ListSortDirection.Ascending));
25: }
26: }
应用程序执行这后的效果如图:
二、实现对数据的筛选
实现对数据的筛选使用的是CollectionView对象的Filter属性,Filter属性的类型是Predicate<object>委托,其要求绑定的方法返回一个布尔值,系统将依据其返回的布尔值筛选数据,使得筛选后的所有数据满足使方法返回True。例如,在前面的例子中添加对单价的筛选条件:
1: <!-- 在界面中添加Grid的一行,并在此行中添加筛选数据所需的界面元素,省略其他代码 -->
2: <WrapPanel Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center">
3: <TextBlock Text="产品单价范围:" />
4: <TextBox Width="50" x:Name="lowPrice" />
5: <TextBlock Text="~" />
6: <TextBox Width="50" x:Name="highPrice" />
7: <Button Content="筛选" Margin="10,0,0,0" Click="Button_Click_1" />
8: </WrapPanel>
在按钮的Click事件中定义如下代码:
1: private void Button_Click_1(object sender, RoutedEventArgs e)
2: {
3: // 获取数据源适配器
4: ObjectDataProvider provider =
5: (ObjectDataProvider)(this.FindResource("myDataSource"));
6: // 获取数据源
7: List<ProductInfo> collections = (List<ProductInfo>)(provider.Data);
8:
9: // 获取数据源对应的CollectionView
10: ICollectionView view = CollectionViewSource.GetDefaultView(collections);
11:
12: if (view.CanFilter)
13: {
14: // 绑定数据筛选的条件
15: view.Filter = new Predicate<object>(dataFilter);
16: }
17: }
18:
19: // 数据筛选的条件
20: private bool dataFilter(object obj)
21: {
22: decimal low = decimal.Parse(lowPrice.Text);
23: decimal high = decimal.Parse(highPrice.Text);
24:
25: ProductInfo info = (ProductInfo) obj;
26:
27: return info.UnitPrice >= low && info.UnitPrice <= high;
28: }
执行的结果如图所示,从中也可以看出,筛选可以和排序一起使用
三、实现数据分组
实现数据分组,使用的是CollectionView的GroupDescriptions集合属性,其包含的元素是GroupDescription抽象类对象,在Framework中,系统定义了一个GroupDescription的子类PropertyGroupDescription,实现根据数据的某属性进行分组的功能。
例如,实现对于产品单价的分组:
在XAML的Grid中添加一行,添加对于分组的显示:
1: <!-- 实现分组的操作,省略其他代码 -->
2: <WrapPanel Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Center">
3: <TextBlock Text="分组条件:" />
4: <RadioButton Content="按单价分组" IsChecked="True" Checked="GroupByUnitPrice_Checked" />
5: <RadioButton Content="按名称分组" Checked="GroupByProductName_Checked" />
6: </WrapPanel>
在后台CS文件中,实现GroupByUnitPrice_Checked方法,实现根据UnitPrice分组:
1: private void GroupByUnitPrice_Checked(object sender, RoutedEventArgs e)
2: {
3: // 获取数据源适配器
4: ObjectDataProvider provider =
5: (ObjectDataProvider)(this.FindResource("myDataSource"));
6: // 获取数据源
7: List<ProductInfo> collections = (List<ProductInfo>)(provider.Data);
8:
9: // 获取数据源对应的CollectionView
10: ICollectionView view = CollectionViewSource.GetDefaultView(collections);
11:
12: if (view.CanGroup)
13: {
14: view.GroupDescriptions.Clear();
15: view.GroupDescriptions.Add(
16: new PropertyGroupDescription("UnitPrice"));
17: }
18: }
执行的结果如下:
定义分组样式:
可以添加ListBox的GroupStyle,以显示分组的样式:
例如:使用默认的分组样式:
1: <ListBox ... >
2: <!-- ... -->
3: <ListBox .GroupStyle>
4: <x:Static Member="GroupStyle.Default" />
5: </ListBox.GroupStyle>
6: </ListBox>
执行的结果如下:
还可以自定义分组样式,例如:
1: <ListBox.GroupStyle>
2: <!--<x:Static Member="GroupStyle.Default" />-->
3: <GroupStyle>
4: <GroupStyle.HeaderTemplate>
5: <DataTemplate>
6: <TextBlock Background="#DDD" Foreground="#333" FontWeight="Bold">
7: <TextBlock Text="{Binding Path=Name}" />
8: (<TextBlock Text="{Binding Path=ItemCount}" />)
9: </TextBlock>
10: </DataTemplate>
11: </GroupStyle.HeaderTemplate>
12: </GroupStyle>
13: </ListBox.GroupStyle>
执行结果如下:
自定义分组条件:
可以通过定义值转换器的方式自定义分组的条件。例如,按产品名称分组时,按照产品名称的第一个字母进行分组,而不是按照完整的名称分组。
定义ProductNameGroupConverter类,实现IValueConverter接口:
1: using System;
2: using System.Globalization;
3: using System.Windows.Data;
4:
5: namespace WPF_24
6: {
7: public class ProductNameGroupConverter : IValueConverter
8: {
9: public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
10: {
11: //将包含产品名称的Object对象value转换为字符串
12: string val = (string)value;
13:
14: return val.Substring(0, 1) + "...";
15: }
16:
17: public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
18: {
19: throw new NotImplementedException();
20: }
21: }
22: }
在GroupByProductName_Checked方法中:
1: private void GroupByProductName_Checked(object sender, RoutedEventArgs e)
2: {
3: // 获取数据源适配器
4: ObjectDataProvider provider =
5: (ObjectDataProvider)(this.FindResource("myDataSource"));
6: // 获取数据源
7: List<ProductInfo> collections = (List<ProductInfo>)(provider.Data);
8:
9: // 获取数据源对应的CollectionView
10: ICollectionView view = CollectionViewSource.GetDefaultView(collections);
11:
12: if (view.CanGroup)
13: {
14: view.GroupDescriptions.Clear();
15: view.GroupDescriptions.Add(
16: new PropertyGroupDescription(
17: "ProductName",
18: new ProductNameGroupConverter()));
19: }
20: }
执行结果如下:
文章来源:http://www.cnblogs.com/DragonInSea/archive/2009/06/08/1498617.html
[转]WPF and Silverlight 学习笔记(二十五):使用CollectionView实现对绑定数据的排序、筛选、分组的更多相关文章
- python3.4学习笔记(二十五) Python 调用mysql redis实例代码
python3.4学习笔记(二十五) Python 调用mysql redis实例代码 #coding: utf-8 __author__ = 'zdz8207' #python2.7 import ...
- Java基础学习笔记二十五 MySQL
MySQL 在dos中操作mysql 连接mysql命令: mysql -uroot -p密码 ,连接OK,会出现mysql> 对数据库的操作 创建一个库 create database 库名 ...
- Java学习笔记二十五:Java面向对象的三大特性之多态
Java面向对象的三大特性之多态 一:什么是多态: 多态是同一个行为具有多个不同表现形式或形态的能力. 多态就是同一个接口,使用不同的实例而执行不同操作. 多态性是对象多种表现形式的体现. 现实中,比 ...
- PHP学习笔记二十五【类的继承】
<?php //定义父类 class Stu{ public $name; protected $age; protected $grade; private $address;//私有变量不会 ...
- angular学习笔记(二十五)-$http(3)-转换请求和响应格式
本篇主要讲解$http(config)的config中的tranformRequest项和transformResponse项 1. transformRequest: $http({ transfo ...
- Python学习笔记(十五)用Python获取本地数据
f1 = open(r'E:\Python\Data\data1.txt') #读取data1.txt文件,使用系统默认缓冲区大小, 为了读取快点,使用缓存吧! f = open(r'E:\Pytho ...
- python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法
python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...
- python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码
python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码 python的json.dumps方法默认会输出成这种格式"\u535a\u ...
- python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字
python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字在字符串里面插入指定分割符的方法,先把字符串变成list然后用join方法变成字符串str=' ...
- python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法
python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法 在Python中字符串处理函数里有三个去空格(包括'\n', '\r', '\t', ' ')的函数 ...
随机推荐
- SpringBoot防止重复请求,重复表单提交超级简单的注解实现
1. 注解接口 /** * @description 防止表单重复提交注解 */@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHO ...
- 分享安装Apache、MySQL、PHP、LAMP的完整教程
Operation timed out after 30000 milliseconds with 0 out of -1 bytes received请注意,在Linux中输入密码时,不会显示您输入 ...
- 阿里云Aliplayer高级功能介绍(一):视频截图
基本介绍 H5 Video是不提供截图的API的, 视频截图需要借助Canvas,通过Canvas提供的drawImage方法,把Video的当前画面渲染到画布上, 最终通过toDataURL方法可以 ...
- MYSQL - database 以及 table 的增删改查
MYSQL - database 以及 table 的增删改查 MySQL的相关概念介绍 MySQL 为关系型数据库(Relational Database Management System), 这 ...
- thinkphp 链接数据库
ThinkPHP内置了抽象数据库访问层,把不同的数据库操作封装起来,我们只需要使用公共的Db类进行操作,而无需针对不同的数据库写不同的代码和底层实现,Db类会自动调用相应的数据库驱动来处理.目前的数据 ...
- 基于VUE利用pdf.js实现文件流形式的pdf显示
首先推荐大家看一下这个demo vue-pdf.js-demo,这里面包含固定本地地址,远程pdf地址,通过打开文件的方式打开pdf 这儿我们着重介绍一下通过文件流的形式打开pdf.(所谓文件流,就是 ...
- 贪心数列构造——cf1157D
一开始将数列设置为0 1 2 3 4 5 6... 然后从左到右遍历,每位不够就增加即可 #include<bits/stdc++.h> using namespace std; #def ...
- python模块typing的作用
一.介绍 Python是一门弱类型的语言,很多时候我们可能不清楚函数参数类型或者返回值类型,很有可能导致一些类型没有指定方法,在写完代码一段时间后回过头看代码,很可能忘记了自己写的函数需要传什么参数, ...
- C#,判断数字集合是否是连续的
/// <summary> /// 判断数字集合是否是连续的 /// </summary> /// <returns></returns> public ...
- iOS开发线程之NSThread
1.初始化 - (instancetype)init API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) NS_DESIGNAT ...