WPF分页DataGrid

http://blog.csdn.net/qing2005/article/details/7612837

最近用到WPF的表格控件,需要使用分页功能,找了很多例子都不是很满意。有些是模仿SL做的DataPager导航条,使用的时候还要和DataGrid组合使用,不是很方便。最好还是继承DataGrid的分页表格控件。 于是自己动手封装了一个分页表格。
见图例:
WPF分页DataGrid_第1张图片
先说思路,然后说实现。
为什么要使用分页这里不是讨论话题,分页表格需要知道两个结果:总记录数和分页数据集,所以必须暴露Total和ItemsSource属性,要查询分页必须传递:页面和每页记录数。
1.分页表格是一个DataGrid,所以继承于DataGrid;
2.添加一些依赖属性,比如:页面、每页记录数等,允许用户自定义设置属性;
3.重写样式,在样式模板中添加分页导航控件;
4.暴露分页事件,用户分页逻辑在事件中实现。
说起来很容易,做起来没一个很容易的。为了分页导航按钮漂亮,我还做了一个ImageButton的用户控件(这里不介绍此控件)

看看部分实现:
1.定义表格模板(比较复杂,不具体一一说明了)
关键在ControlTemplate中加入一个Grid,就是导航控件部分,注意我的绑定方式,不是TemplateBinding。

[html]  view plain copy
  1. <Style x:Key="{x:Type local:PagingDataGrid}" TargetType="{x:Type local:PagingDataGrid}">  
  2.     <Setter Property="Background"  
  3.               Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>  
  4.     <Setter Property="Foreground"  
  5.               Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>  
  6.     <Setter Property="BorderBrush" Value="#FF688CAF" />  
  7.     <Setter Property="BorderThickness" Value="1" />  
  8.     <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected" />  
  9.     <Setter Property="ScrollViewer.CanContentScroll"  
  10.               Value="true"/>  
  11.     <Setter Property="ScrollViewer.PanningMode"  
  12.         Value="Both"/>  
  13.     <Setter Property="Stylus.IsFlicksEnabled"  
  14.         Value="False"/>  
  15.     <Setter Property="Template">  
  16.         <Setter.Value>  
  17.         <ControlTemplate TargetType="{x:Type local:PagingDataGrid}">  
  18.             <Border Background="{TemplateBinding Background}"  
  19.               BorderBrush="{TemplateBinding BorderBrush}"  
  20.               BorderThickness="{TemplateBinding BorderThickness}"  
  21.               SnapsToDevicePixels="True"  
  22.               Padding="{TemplateBinding Padding}">  
  23.             <Grid>  
  24.                 <Grid.RowDefinitions>  
  25.                 <RowDefinition Height="*" />  
  26.                 <RowDefinition Height="Auto" />  
  27.                 </Grid.RowDefinitions>  
  28.                 <ScrollViewer Grid.Row="0"     
  29.                 Focusable="false"  
  30.                 Name="DG_ScrollViewer">  
  31.                 <ScrollViewer.Template>  
  32.                 ……  
  33.                 </ScrollViewer>  
  34.                   
  35.                 <!--分页控件-->  
  36.                 <Grid Grid.Row="1" Visibility="{Binding IsShowPaging,RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource visibilityConverter}}">  
  37.                 <Grid.ColumnDefinitions>  
  38.                     <ColumnDefinition Width="Auto" />  
  39.                     <ColumnDefinition />  
  40.                     <ColumnDefinition Width="Auto" />  
  41.                 </Grid.ColumnDefinitions>  
  42.                 <ComboBox Grid.Column="0"  VerticalAlignment="Center" x:Name="PART_PageSizeList"  
  43.                       MinWidth="40" Margin="5,0,0,0"  
  44.                       ItemsSource="{Binding PageSizeItemsSource,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"   
  45.                       SelectedItem="{Binding PageSize,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />  
  46.                 <StackPanel Grid.Column="1" VerticalAlignment="Center" Orientation="Horizontal" Margin="5,0,0,0">  
  47.   
  48.                     <local:ImageButton x:Name="PART_FirstPage"  
  49.                     ImageSource="/CustomControlLibrary;component/Images/pagination_first.gif"   
  50.                     GrayImageSource="/CustomControlLibrary;component/Images/pagination_first_gray.gif" />  
  51.                     <local:ImageButton x:Name="PART_PerviousPage"  
  52.                     ImageSource="/CustomControlLibrary;component/Images/pagination_prev.gif"   
  53.                     GrayImageSource="/CustomControlLibrary;component/Images/pagination_prev_gray.gif" />  
  54.   
  55.                     <TextBlock Text="Page "  VerticalAlignment="Center"/>  
  56.                     <TextBox Width="30" Text="{Binding PageIndex,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}" x:Name="PART_PageIndex" />  
  57.                     <TextBlock Text=" of "  VerticalAlignment="Center"/>  
  58.                     <TextBlock Text="{Binding PageCount,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}"  VerticalAlignment="Center"/>  
  59.   
  60.                     <local:ImageButton x:Name="PART_NextPage"  
  61.                     ImageSource="/CustomControlLibrary;component/Images/pagination_next.gif"   
  62.                     GrayImageSource="/CustomControlLibrary;component/Images/pagination_next_gray.gif" />  
  63.                     <local:ImageButton x:Name="PART_LastPage"  
  64.                     ImageSource="/CustomControlLibrary;component/Images/pagination_last.gif"   
  65.                     GrayImageSource="/CustomControlLibrary;component/Images/pagination_last_gray.gif" />  
  66.                     <local:ImageButton x:Name="PART_Refresh"  
  67.                     ImageSource="/CustomControlLibrary;component/Images/pagination_load.png" />  
  68.                 </StackPanel>  
  69.                 <TextBlock Grid.Column="2" VerticalAlignment="Center" Margin="5,0,5,0" >  
  70.                     Display <TextBlock Text="{Binding Start,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}" /> to <TextBlock Text="{Binding End,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}" /> of <TextBlock Text="{Binding Total,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}" /> items  
  71.                 </TextBlock>  
  72.                 </Grid>  
  73.             </Grid>  
  74.             </Border>  
  75.         </ControlTemplate>  
  76.         </Setter.Value>  
  77.     </Setter>  
  78.     <Style.Triggers>  
  79.         <Trigger Property="IsGrouping" Value="true">  
  80.         <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>  
  81.         </Trigger>  
  82.     </Style.Triggers>  
  83. </Style>  




2.分页表格类(部分代码,完整见下载中的代码)
其中定义了一些依赖属性,如:PageIndex、PageSize、Total等

[html]  view plain copy
  1. public class PagingDataGrid : DataGrid {  
  2.   
  3.     static PagingDataGrid() {  
  4.         DefaultStyleKeyProperty.OverrideMetadata(typeof(PagingDataGrid), new FrameworkPropertyMetadata(typeof(PagingDataGrid)));  
  5.     }  
  6.   
  7.     #region 依赖属性  
  8.     public int Total {  
  9.         get { return (int)GetValue(TotalProperty); }  
  10.         set { SetValue(TotalProperty, value); }  
  11.     }  
  12.   
  13.     /// <summary>  
  14.     /// 总记录数  
  15.     /// </summary>  
  16.     public static readonly DependencyProperty TotalProperty =  
  17.         DependencyProperty.Register("Total", typeof(int), typeof(PagingDataGrid), new UIPropertyMetadata(0));  
  18.   
  19.   
  20.   
  21.     public int PageSize {  
  22.         get { return (int)GetValue(PageSizeProperty); }  
  23.         set { SetValue(PageSizeProperty, value); }  
  24.     }  
  25.   
  26.     /// <summary>  
  27.     /// 每页记录数,默认:10  
  28.     /// </summary>  
  29.     public static readonly DependencyProperty PageSizeProperty =  
  30.         DependencyProperty.Register("PageSize", typeof(int), typeof(PagingDataGrid), new UIPropertyMetadata(10));  
  31.   
  32.   
  33.   
  34.     public int PageIndex {  
  35.         get { return (int)GetValue(PageIndexProperty); }  
  36.         set { SetValue(PageIndexProperty, value); }  
  37.     }  
  38.   
  39.     /// <summary>  
  40.     /// 当前页码,默认:1  
  41.     /// </summary>  
  42.     public static readonly DependencyProperty PageIndexProperty =  
  43.         DependencyProperty.Register("PageIndex", typeof(int), typeof(PagingDataGrid), new UIPropertyMetadata(1));  
  44.   
  45.   
  46.     public static readonly RoutedEvent PagingChangedEvent = EventManager.RegisterRoutedEvent("PagingChangedEvent", RoutingStrategy.Bubble, typeof(PagingChangedEventHandler), typeof(PagingDataGrid));  
  47.   
  48.     #endregion  
  49.   
  50.     #region 重写方法  
  51.     public override void OnApplyTemplate() {  
  52.         base.OnApplyTemplate();  
  53.   
  54.         //获取模板中的控件  
  55.     //添加控件事件  
  56.     }  
  57.   
  58.     #endregion  
  59.   
  60.     #region 分页事件  
  61.     #endregion  
  62. }  



3.用户界面使用,和DataGrid一样使用,增加几个属性就行了

[html]  view plain copy
  1. <Window x:Class="WpfApplication.MainWindow2"  
  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:CustomControlLibrary;assembly=CustomControlLibrary"  
  5.         Name="self"  
  6.         Title="MainWindow2" Height="325" Width="518">  
  7.     <Grid>  
  8.         <lib:PagingDataGrid   
  9.             PageSizeList="10,20,30"  
  10.             ItemsSource="{Binding Result.Students,ElementName=self}"   
  11.             Total="{Binding Result.Total,ElementName=self}"   
  12.             PagingChanged="PagingDataGrid_PagingChanged">  
  13.             <lib:PagingDataGrid.Columns>  
  14.                 <DataGridTextColumn Header="Name" Binding="{Binding Name}" />  
  15.                 <DataGridTextColumn Header="Age" Binding="{Binding Age}" />  
  16.                 <DataGridTextColumn Header="Gender" Binding="{Binding Gender}" />  
  17.             </lib:PagingDataGrid.Columns>  
  18.         </lib:PagingDataGrid>  
  19.     </Grid>  
  20. </Window>  


4.分页实现,只需要触发事件PagingDataGrid_PagingChanged事件即可

[csharp]  view plain copy
  1. /// <summary>  
  2. /// MainWindow2.xaml 的交互逻辑  
  3. /// </summary>  
  4. public partial class MainWindow2 : Window {  
  5.     public MainWindow2() {  
  6.         Result = new StuResult();  
  7.         InitializeComponent();  
  8.     }  
  9.   
  10.     public StuResult Result { getset; }  
  11.   
  12.     public void Query(int size, int pageIndex) {  
  13.         Result.Total = Student.Students.Count;  
  14.         Result.Students = Student.Students.Skip((pageIndex - 1) * size).Take(size).ToList();  
  15.   
  16.     }  
  17.   
  18.     private void PagingDataGrid_PagingChanged(object sender, CustomControlLibrary.PagingChangedEventArgs args) {  
  19.         Query(args.PageSize, args.PageIndex);  
  20.     }  
  21. }  



代码见我的资源中,下载地址:http://download.csdn.net/detail/qing2005/4337197。

你可能感兴趣的:(WPF分页DataGrid)