• WPF自定义DataGrid分页控件


    新建Custom Control,名:PagingDataGrid

    打开工程下面的ThemesGeneric.xaml

    xaml里面代码替换如下

      1 <Style x:Key="{x:Type loc:PagingDataGrid}" TargetType="{x:Type loc:PagingDataGrid}">
      2         <Setter Property="Background"  Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
      3         <Setter Property="Foreground"  Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
      4         <Setter Property="BorderBrush" Value="#FF688CAF" />
      5         <Setter Property="BorderThickness" Value="1" />
      6         <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected" />
      7         <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
      8         <Setter Property="CanUserSortColumns" Value="False"/>
      9         <Setter Property="AlternatingRowBackground" Value="SkyBlue"/>
     10         <Setter Property="AlternationCount" Value="2"/>
     11         <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
     12         <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
     13         <Setter Property="Template">
     14             <Setter.Value>
     15                 <ControlTemplate TargetType="{x:Type loc:PagingDataGrid}">
     16                     <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True" Padding="{TemplateBinding Padding}">
     17                         <Grid>
     18                             <Grid.RowDefinitions>
     19                                 <RowDefinition Height="*"/>
     20                                 <RowDefinition Height="Auto"/>
     21                             </Grid.RowDefinitions>
     22                             <ScrollViewer Grid.Row="0" Focusable="false" Name="DG_ScrollViewer">
     23                                 <ScrollViewer.Template>
     24                                     <ControlTemplate TargetType="{x:Type ScrollViewer}">
     25                                         <Grid>
     26                                             <Grid.ColumnDefinitions>
     27                                                 <ColumnDefinition Width="Auto"/>
     28                                                 <ColumnDefinition Width="*"/>
     29                                                 <ColumnDefinition Width="Auto"/>
     30                                             </Grid.ColumnDefinitions>
     31                                             <Grid.RowDefinitions>
     32                                                 <RowDefinition Height="Auto"/>
     33                                                 <RowDefinition Height="*"/>
     34                                                 <RowDefinition Height="Auto"/>
     35                                             </Grid.RowDefinitions>
     36                                             <Button Command="ApplicationCommands.SelectAll" Focusable="False" Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}" Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type DataGrid}}}">
     37                                                 <Button.Visibility>
     38                                                     <Binding Path="HeadersVisibility" RelativeSource="{RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type DataGrid}}">
     39                                                         <Binding.ConverterParameter>
     40                                                             <DataGridHeadersVisibility>All</DataGridHeadersVisibility>
     41                                                         </Binding.ConverterParameter>
     42                                                     </Binding>
     43                                                 </Button.Visibility>
     44                                             </Button>
     45                                             <DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1">
     46                                                 <DataGridColumnHeadersPresenter.Visibility>
     47                                                     <Binding Path="HeadersVisibility" RelativeSource="{RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type DataGrid}}">
     48                                                         <Binding.ConverterParameter>
     49                                                             <DataGridHeadersVisibility>Column</DataGridHeadersVisibility>
     50                                                         </Binding.ConverterParameter>
     51                                                     </Binding>
     52                                                 </DataGridColumnHeadersPresenter.Visibility>
     53                                             </DataGridColumnHeadersPresenter>
     54                                             <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" Grid.ColumnSpan="2" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Grid.Row="1"/>
     55                                             <ScrollBar x:Name="PART_VerticalScrollBar" Grid.Column="2" Maximum="{TemplateBinding ScrollableHeight}" Orientation="Vertical" Grid.Row="1" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
     56                                             <Grid Grid.Column="1" Grid.Row="2">
     57                                                 <Grid.ColumnDefinitions>
     58                                                     <ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type DataGrid}}}"/>
     59                                                     <ColumnDefinition Width="*"/>
     60                                                 </Grid.ColumnDefinitions>
     61                                                 <ScrollBar x:Name="PART_HorizontalScrollBar" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}" Orientation="Horizontal" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
     62                                             </Grid>
     63                                         </Grid>
     64                                     </ControlTemplate>
     65                                 </ScrollViewer.Template>
     66                                 <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
     67                             </ScrollViewer>
     68                             <!--分页控件-->
     69                             <StackPanel Grid.Row="1" SnapsToDevicePixels="True" VerticalAlignment="Center" Visibility="{Binding IsShowPaging,RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource BoolToVisibilityConverter}}" Orientation="Horizontal">
     70                                 <StackPanel.Resources>
     71                                     <Style TargetType="TextBlock">
     72                                         <Setter Property="FontSize" Value="13"/>
     73                                         <Setter Property="Margin" Value="3,0"/>
     74                                     </Style>
     75                                     <Style TargetType="TextBox">
     76                                         <Setter Property="FontSize" Value="13"/>
     77                                     </Style>
     78                                     <Style TargetType="ComboBox">
     79                                         <Setter Property="FontSize" Value="13"/>
     80                                     </Style>
     81                                     <Style TargetType="Button">
     82                                         <Setter Property="FontSize" Value="13"/>
     83                                     </Style>
     84                                 </StackPanel.Resources>
     85                                 <TextBlock>总计</TextBlock>
     86                                 <TextBlock Foreground="Red" Text="{Binding Total,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}" />
     87                                 <TextBlock>条记录 每页显示</TextBlock>
     88                                 <ComboBox x:Name="PART_DispalyCount" BorderThickness="1" BorderBrush="Red" Foreground="Red" Grid.Column="0" FontSize="12"  VerticalAlignment="Center" MinWidth="40" ItemsSource="{Binding PageSizeItemsSource,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"  SelectedItem="{Binding PageSize,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
     89                                 <TextBlock>条 总页数</TextBlock>
     90                                 <TextBlock Margin="3" Foreground="Red" Text="{Binding PageCount,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}" />
     91                                 <Button x:Name="PART_PrePage" Content="上一页"/>
     92                                 <TextBlock>当前页</TextBlock>
     93                                 <TextBox Width="100" Foreground="Red" x:Name="PART_PageIndex" Text="{Binding PageIndex,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}" />
     94                                 <TextBlock>页</TextBlock>
     95                                 <Button x:Name="PART_GoTo" Content="转到页"/>
     96                                 <Button x:Name="PART_NextPage" Content="下一页"/>
     97                             </StackPanel>
     98                         </Grid>
     99                     </Border>
    100                 </ControlTemplate>
    101             </Setter.Value>
    102         </Setter>
    103         <Style.Triggers>
    104             <Trigger Property="IsGrouping" Value="true">
    105                 <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
    106             </Trigger>
    107         </Style.Triggers>
    108     </Style>
    View Code


    打开PagingDataGrid.cs文件

    代码如下:

      1 public class PagingDataGrid : DataGrid
      2     {
      3         static PagingDataGrid()
      4         {
      5             DefaultStyleKeyProperty.OverrideMetadata(typeof(PagingDataGrid), new FrameworkPropertyMetadata(typeof(PagingDataGrid)));
      6         }
      7 
      8         #region 变量定义
      9         ComboBox PART_DispalyCount;
     10         Button PART_PrePage;
     11         Button PART_NextPage;
     12         Button PART_GoTo;
     13         TextBox PART_PageIndex;
     14         #endregion
     15 
     16         #region 事件代理
     17 
     18         public delegate void PagingChangedEventHandler(object sender, PagingChangedEventArgs e);
     19 
     20         public event PagingChangedEventHandler PagingChanged;
     21 
     22         private void OnPagingChanged()
     23         {
     24             if (PagingChanged != null)
     25             {
     26                 PagingChanged(this, new PagingChangedEventArgs() { PageIndex = PageIndex, PageSize = PageSize });
     27             }
     28         }
     29         #endregion
     30 
     31         #region 一般属性
     32         private List<Student> dataItems = new List<Student>();
     33 
     34         public List<Student> DataItems
     35         {
     36             get
     37             {
     38                 return dataItems;
     39             }
     40             set
     41             {
     42                 dataItems = value;
     43                 ReCalcLayout();
     44             }
     45         }
     46 
     47         List<int> list = new List<int>();
     48 
     49         public List<int> PageSizeItemsSource
     50         {
     51             get
     52             {
     53                 return list;
     54             }
     55             set
     56             {
     57                 list = value;
     58             }
     59         } 
     60         #endregion
     61 
     62         #region 依赖属性
     63         /// <summary>
     64         /// 页大小
     65         /// </summary>
     66         public int PageSize
     67         {
     68             get { return (int)GetValue(PageSizeProperty); }
     69             set { SetValue(PageSizeProperty, value); }
     70         }
     71 
     72         /// <summary>
     73         /// 当前页
     74         /// </summary>
     75         public int PageIndex
     76         {
     77             get { return (int)GetValue(PageIndexProperty); }
     78             set { SetValue(PageIndexProperty, value); }
     79         }
     80 
     81         /// <summary>
     82         /// 总计录数
     83         /// </summary>
     84         public int Total
     85         {
     86             get { return (int)GetValue(TotalProperty); }
     87             set { SetValue(TotalProperty, value); }
     88         }
     89 
     90         /// <summary>
     91         /// 是否显示页
     92         /// </summary>
     93         public bool IsShowPaging
     94         {
     95             get { return (bool)GetValue(IsShowPagingProperty); }
     96             set { SetValue(IsShowPagingProperty, value); }
     97         }
     98 
     99         /// <summary>
    100         /// 总页数
    101         /// </summary>
    102         public int PageCount
    103         {
    104             get { return (int)GetValue(PageCountProperty); }
    105             set { SetValue(PageCountProperty, value); }
    106         }
    107 
    108 
    109 
    110         // Using a DependencyProperty as the backing store for PageCount.  This enables animation, styling, binding, etc...
    111         public static readonly DependencyProperty PageCountProperty =
    112             DependencyProperty.Register("PageCount", typeof(int), typeof(PagingDataGrid), new UIPropertyMetadata(5));
    113 
    114 
    115         // Using a DependencyProperty as the backing store for End.  This enables animation, styling, binding, etc...
    116         public static readonly DependencyProperty EndProperty =
    117             DependencyProperty.Register("End", typeof(int), typeof(PagingDataGrid), new UIPropertyMetadata(0));
    118 
    119 
    120         // Using a DependencyProperty as the backing store for Start.  This enables animation, styling, binding, etc...
    121         public static readonly DependencyProperty StartProperty =
    122             DependencyProperty.Register("Start", typeof(int), typeof(PagingDataGrid), new UIPropertyMetadata(0));
    123 
    124 
    125         // Using a DependencyProperty as the backing store for IsShowPaging.  This enables animation, styling, binding, etc...
    126         public static readonly DependencyProperty IsShowPagingProperty =
    127             DependencyProperty.Register("IsShowPaging", typeof(bool), typeof(PagingDataGrid), new UIPropertyMetadata(true));
    128 
    129 
    130         // Using a DependencyProperty as the backing store for Total.  This enables animation, styling, binding, etc...
    131         public static readonly DependencyProperty TotalProperty =
    132             DependencyProperty.Register("Total", typeof(int), typeof(PagingDataGrid), new UIPropertyMetadata(16));
    133 
    134 
    135         // Using a DependencyProperty as the backing store for PageIndex.  This enables animation, styling, binding, etc...
    136         public static readonly DependencyProperty PageIndexProperty =
    137             DependencyProperty.Register("PageIndex", typeof(int), typeof(PagingDataGrid), new UIPropertyMetadata(1));
    138 
    139 
    140         // Using a DependencyProperty as the backing store for PageSize.  This enables animation, styling, binding, etc...
    141         public static readonly DependencyProperty PageSizeProperty =
    142             DependencyProperty.Register("PageSize", typeof(int), typeof(PagingDataGrid), new UIPropertyMetadata(10));
    143 
    144         #endregion
    145 
    146         #region 相关命令
    147         RoutedCommand NextPageCommand = new RoutedCommand();
    148         RoutedCommand PrePageCommand = new RoutedCommand();
    149         RoutedCommand GoToCommand = new RoutedCommand();
    150         #endregion
    151 
    152         #region 重写方法
    153         public override void OnApplyTemplate()
    154         {
    155             base.OnApplyTemplate();
    156             //获取模板中的控件  
    157             PART_DispalyCount = GetTemplateChild("PART_DispalyCount") as ComboBox;
    158             PART_PrePage = GetTemplateChild("PART_PrePage") as Button;
    159             PART_NextPage = GetTemplateChild("PART_NextPage") as Button;
    160             PART_GoTo = GetTemplateChild("PART_GoTo") as Button;
    161             PART_PageIndex = GetTemplateChild("PART_PageIndex") as TextBox;
    162             //添加控件命令Binding  
    163             PART_NextPage.CommandBindings.Add(new CommandBinding(NextPageCommand, NextPage_Excuted, NextPage_CanExcuted));
    164             PART_PrePage.CommandBindings.Add(new CommandBinding(PrePageCommand, PrePage_Excuted, PrePage_CanExcuted));
    165             PART_GoTo.CommandBindings.Add(new CommandBinding(GoToCommand, GoTo_Excuted, GoTo_CanExcuted));
    166             PART_NextPage.Command = NextPageCommand;
    167             PART_PrePage.Command = PrePageCommand;
    168             PART_GoTo.Command = GoToCommand;
    169             //添加控件事件
    170             PART_DispalyCount.SelectionChanged += PART_DispalyCount_SelectionChanged;
    171         }
    172 
    173         private void GoTo_Excuted(object sender, ExecutedRoutedEventArgs e)
    174         {
    175             int idx = 0;
    176             if (int.TryParse(PART_PageIndex.Text, out idx))
    177             {
    178                 GoTo(idx);
    179             }
    180         }
    181 
    182         private void GoTo_CanExcuted(object sender, CanExecuteRoutedEventArgs e)
    183         {
    184             int idx = 0;
    185             if (int.TryParse(PART_PageIndex.Text, out idx))
    186             {
    187                 if (idx > PageCount || idx <= 0)
    188                 {
    189                     e.CanExecute = false;
    190                 }
    191                 else
    192                 {
    193                     e.CanExecute = true;
    194                 }
    195             }
    196             else
    197             {
    198                 e.CanExecute = false;
    199             }
    200         }
    201 
    202         private void NextPage_CanExcuted(object sender, CanExecuteRoutedEventArgs e)
    203         {
    204             if (PageIndex == PageCount)
    205             {
    206                 e.CanExecute = false;
    207             }
    208             else
    209             {
    210                 e.CanExecute = true;
    211             }
    212         }
    213 
    214         private void NextPage_Excuted(object sender, ExecutedRoutedEventArgs e)
    215         {
    216             GoTo(PageIndex++);            
    217         }
    218 
    219         private void PrePage_CanExcuted(object sender, CanExecuteRoutedEventArgs e)
    220         {
    221             if (PageIndex == 1)
    222             {
    223                 e.CanExecute = false;
    224             }
    225             else
    226             {
    227                 e.CanExecute = true;
    228             }
    229         }
    230 
    231         private void PrePage_Excuted(object sender, ExecutedRoutedEventArgs e)
    232         {
    233             GoTo(PageIndex--);
    234         }
    235         #endregion
    236 
    237         #region 分页事件
    238         void PART_DispalyCount_SelectionChanged(object sender, SelectionChangedEventArgs e)
    239         {
    240             PageSize = int.Parse((sender as ComboBox).SelectedItem.ToString());
    241             ReCalcLayout();
    242             GoTo(PageIndex);
    243         }
    244 
    245         private void GoTo(int page)
    246         {
    247             ItemsSource = DataItems.Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
    248         }
    249 
    250         private void ReCalcLayout()
    251         {
    252             Total = DataItems.Count;
    253             int pc = Total / PageSize;
    254             if (Total % PageSize == 0)
    255             {
    256                 PageCount = pc;
    257             }
    258             else
    259             {
    260                 PageCount = pc + 1;
    261             }
    262             PageIndex = PageIndex > PageCount ? PageCount : PageIndex;
    263         }
    264         #endregion
    265     }
    View Code


    此外还需要一个类支持PagingChangedEventArgs

    1 /// <summary>
    2     /// 页跳转参数
    3     /// </summary>
    4     public class PagingChangedEventArgs : EventArgs
    5     {
    6         public int PageSize { get; set; }
    7         public int PageIndex { get; set; }
    8     }
    View Code


    控件完成,调试:

     1 <local:PagingDataGrid x:Name="pdg" PagingChanged="pdg_PagingChanged" IsShowPaging="True" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" IsReadOnly="True" SnapsToDevicePixels="True" CanUserReorderColumns="False">
     2                             <local:PagingDataGrid.PageSizeItemsSource>
     3                                 <sys:Int32>5</sys:Int32>
     4                                 <sys:Int32>10</sys:Int32>
     5                                 <sys:Int32>15</sys:Int32>
     6                                 <sys:Int32>20</sys:Int32>
     7                                 <sys:Int32>30</sys:Int32>
     8                                 <sys:Int32>50</sys:Int32>
     9                                 <sys:Int32>100</sys:Int32>
    10                             </local:PagingDataGrid.PageSizeItemsSource>
    11                             <local:PagingDataGrid.Columns>
    12                                 <DataGridTextColumn Binding="{Binding Name}" Header="AAA"/>
    13                                 <DataGridTextColumn Binding="{Binding Age}" Header="BBB"/>
    14                                 <DataGridTextColumn Binding="{Binding Sex}" Width="*" Header="CCC"/>
    15                             </local:PagingDataGrid.Columns>
    16                         </local:PagingDataGrid>
    View Code

    新建调试类Student

    1     public class Student
    2     {
    3         public string Name { get; set; }
    4         public int Age { get; set; }
    5         public string MoreInfo { get; set; }
    6     }
    View Code

    调试代码,注意这里使用DataItems保存信息,如果使用Items或是ItemsSource则无分页效果

    1 List<Student> list = new List<Student>();
    2             for (int i = 0; i < 20; i++)
    3             {
    4                 list.Add(new Student() { Name = Guid.NewGuid().ToString(), Age = i, MoreInfo = "Sex" });
    5             }
    6             pdg.DataItems = list;
    View Code
  • 相关阅读:
    computed的用法
    地址列表展开功能/默认选中功能
    简易编辑器
    用vue做todolist
    用vue做的购物车结算的功能
    如果数据返回没有那个字段,怎么加上去?
    vue中全局filter和局部filter怎么用?
    editorconfig
    eslint 配置
    react typescript 单元测试
  • 原文地址:https://www.cnblogs.com/liguoxi134/p/3310097.html
Copyright © 2020-2023  润新知