在第二十三节,我们使用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实现对绑定数据的排序、筛选、分组的更多相关文章

  1. python3.4学习笔记(二十五) Python 调用mysql redis实例代码

    python3.4学习笔记(二十五) Python 调用mysql redis实例代码 #coding: utf-8 __author__ = 'zdz8207' #python2.7 import ...

  2. Java基础学习笔记二十五 MySQL

    MySQL 在dos中操作mysql 连接mysql命令: mysql -uroot -p密码 ,连接OK,会出现mysql> 对数据库的操作 创建一个库 create database 库名 ...

  3. Java学习笔记二十五:Java面向对象的三大特性之多态

    Java面向对象的三大特性之多态 一:什么是多态: 多态是同一个行为具有多个不同表现形式或形态的能力. 多态就是同一个接口,使用不同的实例而执行不同操作. 多态性是对象多种表现形式的体现. 现实中,比 ...

  4. PHP学习笔记二十五【类的继承】

    <?php //定义父类 class Stu{ public $name; protected $age; protected $grade; private $address;//私有变量不会 ...

  5. angular学习笔记(二十五)-$http(3)-转换请求和响应格式

    本篇主要讲解$http(config)的config中的tranformRequest项和transformResponse项 1. transformRequest: $http({ transfo ...

  6. Python学习笔记(十五)用Python获取本地数据

    f1 = open(r'E:\Python\Data\data1.txt') #读取data1.txt文件,使用系统默认缓冲区大小, 为了读取快点,使用缓存吧! f = open(r'E:\Pytho ...

  7. python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法

    python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...

  8. python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码

    python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码 python的json.dumps方法默认会输出成这种格式"\u535a\u ...

  9. python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字

    python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字在字符串里面插入指定分割符的方法,先把字符串变成list然后用join方法变成字符串str=' ...

  10. python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法

    python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法 在Python中字符串处理函数里有三个去空格(包括'\n', '\r', '\t', ' ')的函数 ...

随机推荐

  1. 微信公众号支付出现:“当前页面的URL未注册”

    微信公众号H5调起支付时,点击支付按钮出现“当前页面的URL未注册”的提示.解决办法:由于2017年8月1日微信官方把关于支付的信息转移到了商户平台:公众平台微信支付公众号支付授权目录.扫码支付回调U ...

  2. 阿里云ECS发送邮件失败

    阿里云发送SMTP邮件失败   N多测试发现 阿里云服务器不能用25端口发邮件,配置465端口阿里云发送邮件是成功的 修改mail.rc 里的smtp 端口为465 配置如下 set from=*** ...

  3. sql语句之分组

    对聚合函数的结果进行筛选用having,不能用where

  4. thinkphp 系统流程

    用户URL请求 调用应用入口文件(通常是网站的index.php) 载入框架入口文件(ThinkPHP.php) 记录初始运行时间和内存开销 系统常量判断及定义 载入框架引导类(Think\Think ...

  5. 0917CSP-S模拟测试赛后总结

    机房搬家后的首战,便是失利. 依旧是挂掉了.这次状态有大问题. 然而状态的问题归根结底还是实力不行. 大约一个小时左右我拿到了T1的部分分.赛时判断了一下大概是高分. (不过赛后发现确实不算什么太高的 ...

  6. Delphi窗体间发送消息或字符串

    在Delphi 开发中,常常应用到窗体消息传递,以达成某种操作要求,以下列举一个应用的例子,供大家参考. 自定义过程/函数方法://发送字符串到指字句柄的窗口中 (接收窗体需用发送时的消息常量WM_C ...

  7. PAT甲级——A1121 Damn Single【25】

    "Damn Single (单身狗)" is the Chinese nickname for someone who is being single. You are suppo ...

  8. 如何将指定文件或文件夹直接提交到svn指定目录?

    如何将指定文件或文件夹直接提交到svn指定目录? 一般我们都是按以下步骤操作的: 1.先将那个目录checkout下来 2.将要添加的文件或者文件夹放到这个目录中 3.右击文件执行svn菜单中的add ...

  9. Hadoop完全分布式配置

    ***** 全部三个节点 *****1. 关闭防火墙 service iptables stop chkconfig iptables off2. 修改主机名,Hadoop主机名中不能出现_和- vi ...

  10. Django的日常-模型层(2)

    目录 Django的日常-模型层(2) 几种常用的查询方式 聚合查询 分组查询 F和Q查询 查询优化相关 orm中常见字段 choices参数 orm的事务操作 Django的日常-模型层(2) 几种 ...