
实际开发中,我们可能需要自己写一些自定义的分页设计,所以我们需要学会自己封装一个可以直接套用的分页控件,以下就是一个完整的用例,话不多说,我们直接上代码实现。
1.新建一个分页控件View:PaginationControl
1.1 UI展示如下
<UserControl x:Class="WPFDemoMVVM.Controls.PaginationControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFDemoMVVM.Controls"
xmlns:cov="clr-namespace:WPFDemoMVVM.Converters"
xmlns:lang="clr-namespace:WPFDemoMVVM.Resources"
xmlns:lex="http://wpflocalizeextension.codeplex.com"
lex:ResxLocalizationProvider.DefaultAssembly="WPFDemoMVVM"
lex:ResxLocalizationProvider.DefaultDictionary="Lang"
lex:LocalizeDictionary.DesignCulture="zh-CN"
mc:Ignorable="d"
d:DesignHeight="30" d:DesignWidth="600" Height="30" Width="780" x:Name="Pagination" >
<UserControl.Resources>
<Style x:Key="PgBaseButtonStyle" TargetType="Button" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="6"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="#282B3B"/>
<Setter Property="BorderBrush" Value="#367AFF"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Width" Value="70"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Margin" Value="5 0"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Opacity" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="PgComBoxStyle" TargetType="ComboBox">
<Setter Property="Background" Value="#0D0D19"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Margin" Value="20,0,0,0"/>
<Setter Property="Height" Value="32"/>
<Setter Property="Width" Value="80"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="BorderBrush" Value="#367AFF"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontFamily" Value="Arial"/>
</Style>
<Style TargetType="TextBlock" x:Key="BaseTextBlockStyle">
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="Background" Value="{x:Null}"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Padding" Value="0"/>
</Style>
<Style x:Key="BaseComboBoxStyle" TargetType="ComboBox">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#0D0D19"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Width" Value="80"/>
<Setter Property="Height" Value="32"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="5,0,5,0"/>
<Setter Property="IsEditable" Value="False"/>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" Style="{StaticResource BaseTextBlockStyle}" HorizontalAlignment="Center"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton
Name="ToggleButton"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}" Width="{TemplateBinding Width}">
<Grid>
<ContentPresenter
Name="ContentSite"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
VerticalAlignment="Center"
HorizontalAlignment="Left" Width="60"
Margin="5,0,0,0"
RecognizesAccessKey="True"/>
<Path
HorizontalAlignment="Right"
Margin="0,0,6,0"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z"
Fill="White"/>
</Grid>
</ToggleButton>
<Popup
Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Grid
Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="200"
Background="#0D0D19">
<Border x:Name="DropDownBorder" BorderThickness="0" Background="#0D0D19"/>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="Gray"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#1A1A2A"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TextBox" x:Key="BaseTextBoxStyle">
<Setter Property="Height" Value="32"/>
<Setter Property="Width" Value="98"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="Opacity" Value="0.8"/>
<Setter Property="Background" Value="#0C0E1A"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<!-- 设置光标颜色为白色 -->
<Setter Property="CaretBrush" Value="White"/>
<!--<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>-->
</Style>
<cov:FormatStringMultiConverter x:Key="FormatStringMultiConverter"/>
</UserControl.Resources>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="{lex:Loc HomePage}" Command="{Binding FirstPageCommand}" Style="{DynamicResource ResourceKey=PgBaseButtonStyle}"/>
<Button Content="{lex:Loc PrevPage}" Command="{Binding PrevPageCommand}" Style="{DynamicResource ResourceKey=PgBaseButtonStyle}" />
<TextBlock Margin="10,0" Text="{Binding PageStatus}" Style="{DynamicResource ResourceKey=BaseTextBlockStyle}" Width="auto" FontSize="14"/>
<Button Content="{lex:Loc NextPage}" Command="{Binding NextPageCommand}" Style="{DynamicResource ResourceKey=PgBaseButtonStyle}"/>
<Button Content="{lex:Loc LastPage}" Command="{Binding LastPageCommand}" Style="{DynamicResource ResourceKey=PgBaseButtonStyle}"/>
<TextBlock Text="{lex:Loc PageSize}" VerticalAlignment="Center" Style="{DynamicResource ResourceKey=BaseTextBlockStyle}" FontSize="14"/>
<ComboBox ItemsSource="{Binding PageSizeOptions, Mode=OneWay}" SelectedItem="{Binding PageSize, Mode=TwoWay}" Style="{DynamicResource BaseComboBoxStyle}"/>
<TextBlock Text="{lex:Loc Total}" VerticalAlignment="Center" Style="{DynamicResource ResourceKey=BaseTextBlockStyle}" Margin="5" FontSize="14"/>
<TextBox Text="{Binding TotalItems}" Style="{DynamicResource ResourceKey=BaseTextBoxStyle}" IsEnabled="False"></TextBox>
</StackPanel>
</UserControl>
1.2 分页控件的ViewModel:
public partial class PagingViewModel : ObservableObject
{
public PagingViewModel()
{
PageSizeOptions = new ObservableCollection<int> { 10, 20, 50 };
PageSize = 10;
CurrentPage = 1;
Language = "zh-CN";
}
[ObservableProperty]
private int currentPage;
[ObservableProperty]
private int pageSize;
[ObservableProperty]
private int totalItems;
[ObservableProperty]
private string language;
[ObservableProperty]
private ObservableCollection<int> pageSizeOptions;
public int TotalPages => PageSize == 0 ? 1 : (int)Math.Ceiling((double)TotalItems / PageSize);
public string PageStatus => Language == "zh-CN" ? $"第 {CurrentPage} / {TotalPages} 页" : $"page {CurrentPage} of {TotalPages}";
// 每当这些属性改变时,通知依赖属性的更新
partial void OnCurrentPageChanged(int value)
{
OnPropertyChanged(nameof(PageStatus));
}
partial void OnPageSizeChanged(int value)
{
CurrentPage = 1;
OnPropertyChanged(nameof(TotalPages));
OnPropertyChanged(nameof(PageStatus));
GoToPage(CurrentPage);
}
partial void OnTotalItemsChanged(int value)
{
OnPropertyChanged(nameof(TotalPages));
OnPropertyChanged(nameof(PageStatus));
}
partial void OnLanguageChanged(string value)
{
OnPropertyChanged(nameof(PageStatus));
}
[RelayCommand]
private void FirstPage() => GoToPage(1);
[RelayCommand]
private void PrevPage() => GoToPage(Math.Max(1, CurrentPage - 1));
[RelayCommand]
private void NextPage() => GoToPage(Math.Min(TotalPages, CurrentPage + 1));
[RelayCommand]
private void LastPage() => GoToPage(TotalPages);
private void GoToPage(int page)
{
CurrentPage = page;
PageChanged?.Invoke(CurrentPage, PageSize);
}
public event Action<int, int> PageChanged;
}
2.DataGrid 界面展示如下:
2.1 UI展示效果如下:
<Window x:Class="WPFDemoMVVM.View.DataGridView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFDemoMVVM.View"
xmlns:hr="clr-namespace:WPFDemoMVVM.Helpers"
xmlns:be="clr-namespace:WPFDemoMVVM.Behaviors"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:pg="clr-namespace:WPFDemoMVVM.Controls"
xmlns:lang="clr-namespace:WPFDemoMVVM.Resources"
xmlns:lex="http://wpflocalizeextension.codeplex.com"
lex:ResxLocalizationProvider.DefaultAssembly="WPFDemoMVVM"
lex:ResxLocalizationProvider.DefaultDictionary="Lang"
lex:LocalizeDictionary.DesignCulture="zh-CN"
mc:Ignorable="d"
Title="DataGridView" Height="600" Width="800">
<Window.Resources>
<CollectionViewSource x:Key="view" Filter="CollectionViewSource_Filter"/>
<!--datagrid样式-->
<Style x:Key="DataGridStyleCommon" TargetType="DataGrid">
<Setter Property="RowHeight" Value="40"/>
<Setter Property="Background" Value="#191D2A" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Foreground" Value="White"/>
<Setter Property="Opacity" Value="1"/>
<!--该属性指示是否允许用户调整列宽度-->
<Setter Property="CanUserResizeColumns" Value="false" />
<!--网格线颜色-->
<Setter Property="VerticalGridLinesBrush" Value="{x:Null}"/>
<Setter Property="IsReadOnly" Value="True"></Setter>
<Setter Property="HorizontalGridLinesBrush">
<Setter.Value>
<SolidColorBrush Color="#10FFFFFF" />
<!--网格透明度-->
</Setter.Value>
</Setter>
<!--<Setter Property="VerticalGridLinesBrush">
<Setter.Value>
<SolidColorBrush Color="#FFEA8777" />
</Setter.Value>
</Setter>-->
<!--表格字段显示手动完成-->
<Setter Property="AutoGenerateColumns" Value="False"></Setter>
<!--隔行换色 -->
<Setter Property="AlternationCount" Value="3"></Setter>
<!--DataGrid控件模板-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" x:Name="border"
Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
<ScrollViewer.Template>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="col_rowheader" Width="1" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!--选中所有行-->
<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}}}">
<Button.Visibility>
<Binding Path="HeadersVisibility" RelativeSource="{RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type DataGrid}}">
<Binding.ConverterParameter>
<DataGridHeadersVisibility>All</DataGridHeadersVisibility>
</Binding.ConverterParameter>
</Binding>
</Button.Visibility>
</Button>
<!--表格头部-->
<DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1" Grid.ColumnSpan="2"
Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" >
</DataGridColumnHeadersPresenter>
<!--主数据区-->
<Grid Grid.Row="1" Grid.ColumnSpan="2">
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" Grid.ColumnSpan="2" />
</Grid>
<!--垂直滑动条-->
<ScrollBar x:Name="PART_VerticalScrollBar" Grid.Column="2" Maximum="{TemplateBinding ScrollableHeight}"
Orientation="Vertical" Grid.Row="0" Grid.RowSpan="3" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
ViewportSize="{TemplateBinding ViewportHeight}" />
<!--横向滑动条-->
<!--
<ScrollBar x:Name="PART_HorizontalScrollBar" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2"
Maximum="{TemplateBinding ScrollableWidth}" Orientation="Horizontal"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
ViewportSize="{TemplateBinding ViewportWidth}" />-->
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="1" TargetName="border" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</Trigger>
</Style.Triggers>
</Style>
<!--行头部样式-->
<Style x:Key="DataGridRowHeaderStyleCommon" TargetType="DataGridRowHeader">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Margin" Value="0,0,0,0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRowHeader}">
<Grid>
<Border BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
Margin="{TemplateBinding Margin}"
SnapsToDevicePixels="True">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--标题栏 列头部样式-->
<Style x:Key="DataGridColumnHeaderStyleCommon" TargetType="DataGridColumnHeader">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="MinWidth" Value="15" />
<Setter Property="MinHeight" Value="28" />
<!--<Setter Property="Foreground" Value="#FF0FA459" />-->
<Setter Property="Foreground" Value="{DynamicResource textBoxWhiteColor}" />
<Setter Property="FontSize" Value="14" />
<!--<Setter Property="Cursor" Value="Hand" />-->
<Setter Property="Height" Value="30" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridColumnHeader">
<!--设置表头的背景等样式-->
<Border x:Name="BackgroundBorder" Background="{DynamicResource backgroundGrayColor}" BorderThickness="0" BorderBrush="{DynamicResource borderBrushCommonColor}" Width="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!--内容-->
<ContentPresenter Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Center" />
<!--排序图标-->
<Path x:Name="SortArrow" Visibility="Collapsed" Data="M0,0 L1,0 0.5,1 z" Stretch="Fill" Grid.Column="2"
Width="8" Height="6" Fill="{DynamicResource textBoxWhiteColor}" Margin="0,0,50,0" VerticalAlignment="Center" RenderTransformOrigin="1,1" />
<!--分割线-->
<Rectangle Visibility="Collapsed" Width="1" Fill="#d6c79b" HorizontalAlignment="Right" Grid.ColumnSpan="1" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--行样式触发-->
<!--背景色改变必须先设置cellStyle 因为cellStyle会覆盖rowStyle样式-->
<Style x:Key="DataGridRowStyleCommon" TargetType="DataGridRow">
<Setter Property="Background" Value="#0D0D19"/>
<Setter Property="Height" Value="40" />
<Setter Property="Foreground" Value="White" />
<Style.Triggers>
<!--隔行换色-->
<!--<Trigger Property="AlternationIndex" Value="0">
<Setter Property="Background" Value="{x:Null}" />
</Trigger>-->
<!--<Trigger Property="AlternationIndex" Value="1">
<Setter Property="Background" Value="#FFD4C9F9" />
</Trigger>
<Trigger Property="AlternationIndex" Value="2">
<Setter Property="Background" Value="#FFFFCFC7" />
</Trigger>-->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#191D2A" />
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Opacity" Value="0.6"></Setter>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<!--<Setter Property="Foreground" Value="#FFF31006" />-->
<Setter Property="Opacity" Value="1"></Setter>
<Setter Property="Background" Value="#1D1D2A"/>
</Trigger>
</Style.Triggers>
</Style>
<!--单元格样式触发-->
<Style x:Key="DataGridCellStyleCommon" TargetType="DataGridCell">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridCell">
<TextBlock TextAlignment="Center" VerticalAlignment="Center">
<ContentPresenter />
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="White" />
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="40"/>
<RowDefinition Height="80"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Height="500" Width="auto">
<DataGrid Name="userInfoGrid" AutoGenerateColumns="False" Height="440" HorizontalAlignment="Left" HorizontalContentAlignment="Center" VerticalAlignment="Top" IsReadOnly="True" CanUserAddRows="False" VerticalScrollBarVisibility="Auto" EnableRowVirtualization="False"
Style="{DynamicResource ResourceKey=DataGridStyleCommon}"
RowHeaderStyle="{DynamicResource ResourceKey=DataGridRowHeaderStyleCommon}"
ColumnHeaderStyle="{DynamicResource ResourceKey=DataGridColumnHeaderStyleCommon}"
RowStyle="{DynamicResource ResourceKey=DataGridRowStyleCommon}"
CellStyle="{DynamicResource ResourceKey=DataGridCellStyleCommon}" Margin="2 0 5 0" BorderThickness="1" ItemsSource="{Binding CollectionView,Mode=OneWay}"
hr:MultiSelectorHelper.MonitorSelectionChanged="True"
hr:MultiSelectorHelper.BindableSelectedItems="{Binding SelectedItems,Mode=OneWayToSource}"
>
<i:Interaction.Behaviors>
<be:SelectedItemsBehavior BindableSelectedItems="{Binding SelectedItems,Mode=OneWayToSource}"/>
</i:Interaction.Behaviors>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Index}" CanUserSort="False" IsReadOnly="True" Width="50">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{lex:Loc Number}"/>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Name}" CanUserSort="False" IsReadOnly="True" Width="*">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{lex:Loc AccountName}"/>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Salary}" CanUserSort="False" IsReadOnly="True" Width="*">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{lex:Loc Salary}"/>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
<pg:PaginationControl x:Name="pageControl" Grid.Row="1" DataContext="{Binding Pagination}" VerticalAlignment="Bottom" Background="#191D2A" Height="40">
</pg:PaginationControl>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<!--<TextBox x:Name="queryKeyword" Width="200" Height="50" TextChanged="queryKeyword_TextChanged"/>-->
<TextBlock Text="{lex:Loc AccountName}" Style="{DynamicResource TextBlockBaseStyle}" Margin="5"/>
<TextBox x:Name="queryKeyword" Text="{Binding QueryKeyword,UpdateSourceTrigger=PropertyChanged}" Width="200" Height="32" Margin="5"/>
<Button Margin="5" Content="{lex:Loc Add}" Command="{Binding AddCommand}"/>
<Button Margin="5" Content="{lex:Loc Delete}" Command="{Binding DeleteCommand}"/>
<Button Margin="5" Content="{lex:Loc Calculate}" Command="{Binding CalculateSumSalaryCommand}" CommandParameter="{Binding ElementName=userInfoGrid,Path=SelectedItems}"/>
<TextBox Text="{Binding TotalSalary}" Width="200" Height="32" Margin="5"/>
</StackPanel>
</Grid>
</Window>
2.2 实现Viewmodel业务逻辑如下:
public partial class DataGridViewModel :ObservableObject
{
public List<EmployeeModel> employees;
[ObservableProperty]
ICollectionView collectionView;
[ObservableProperty]
string queryKeyword;
[ObservableProperty]
IList selectedItems;
[ObservableProperty]
private double totalSalary;
[ObservableProperty]
public PagingViewModel pagination;
public DataGridViewModel()
{
ChangeLanguage("zh-CN");
Pagination = new PagingViewModel();
Pagination.PageChanged += OnPageChanged;
IEnumerable<EmployeeModel> employees =EmployeeModel.FakeMany(10);
this.employees = new List<EmployeeModel>(employees);
var pageData = this.employees
.Skip((Pagination.CurrentPage - 1) * Pagination.PageSize)
.Take(Pagination.PageSize)
.Select((e, i) =>
{
e.Index = (Pagination.CurrentPage - 1) * Pagination.PageSize + i + 1;
return e;
}).ToList();
CollectionView = CollectionViewSource.GetDefaultView(pageData);
Pagination.TotalItems = this.employees.Count;
}
partial void OnQueryKeywordChanged(string value)
{
Pagination.CurrentPage = 1; // 筛选后回到第一页
OnPageChanged(Pagination.CurrentPage, Pagination.PageSize);
}
private void OnPageChanged(int currentPage, int pageSize)
{
var filtered = employees.Where(e => string.IsNullOrEmpty(QueryKeyword) || e.Name.Contains(QueryKeyword, StringComparison.OrdinalIgnoreCase)).ToList();
Pagination.TotalItems = filtered.Count;
//重新生成索引 number从1开始
var pageData = filtered
.Skip((currentPage - 1) * pageSize)
.Take(pageSize)
.Select((e, i) =>
{
e.Index = (currentPage - 1) * pageSize + i + 1;
return e;
}).ToList();
CollectionView = CollectionViewSource.GetDefaultView(pageData);
}
[RelayCommand]
private void ChangeLanguage(string languageCode)
{
var culture = new CultureInfo(languageCode);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
LocalizeDictionary.Instance.Culture = culture;
}
[RelayCommand]
public void Add()
{
employees.Add(EmployeeModel.FakeOne());
OnPageChanged(Pagination.CurrentPage, Pagination.PageSize);
}
[RelayCommand]
public void Delete()
{
if (SelectedItems != null)
{
employees.RemoveAll(e => SelectedItems.Contains(e));
OnPageChanged(Pagination.CurrentPage, Pagination.PageSize);
}
}
[RelayCommand]
public void CalculateSumSalary()
{
if (SelectedItems != null)
{
var sum = SelectedItems.Cast<EmployeeModel>().Sum(x => ((EmployeeModel)x).Salary);
TotalSalary = sum;
}
foreach (var item in employees)
{
item.IsSelected = item.Salary > 15000;
}
collectionView.Refresh();
}
}
3.运行效果如下
源代码地址:https://gitee.com/chenshibao/wpfdemo.git
如果本文介绍对你有帮助,可以一键四连:点赞+评论+收藏+推荐,谢谢!