<UserControl.Resources>
<cov:FormatStringMultiConverter x:Key="FormatStringMultiConverter"/> </UserControl.Resources>
1.2 分页控件的ViewModel: public partial class PagingViewModel : ObservableObject { public PagingViewModel() { PageSizeOptions = new ObservableCollection { 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 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.Resources> </Window.Resources> <Grid.RowDefinitions> </Grid.RowDefinitions> <i:Interaction.Behaviors> <be:SelectedItemsBehavior BindableSelectedItems="{Binding SelectedItems,Mode=OneWayToSource}"/> </i:Interaction.Behaviors> <DataGrid.Columns> <DataGridTextColumn.HeaderTemplate> </DataGridTextColumn.HeaderTemplate> <DataGridTextColumn.HeaderTemplate> </DataGridTextColumn.HeaderTemplate> <DataGridTextColumn.HeaderTemplate> </DataGridTextColumn.HeaderTemplate> </DataGrid.Columns> <pg:PaginationControl x:Name="pageControl" Grid.Row="1" DataContext="{Binding Pagination}" VerticalAlignment="Bottom" Background="#191D2A" Height="40"> </pg:PaginationControl> 2.2 实现Viewmodel业务逻辑如下: public partial class DataGridViewModel :ObservableObject { public List employees; [ObservableProperty] ICollectionView collectionView; [ObservableProperty] string queryKeyword; [ObservableProperty] IList selectedItems; [ObservableProperty] private double totalSalary; [ObservableProperty] public PagingViewModel pagination; public DataGridViewModel() { Pagination = new PagingViewModel(); Pagination.PageChanged += OnPageChanged; ChangeLanguage("zh-CN"); IEnumerable employees =EmployeeModel.FakeMany(10); this.employees = new List(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) { SelectedLanguage=languageCode; Pagination.Language = 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().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 如果本文介绍对你有帮助,可以一键四连:点赞+评论+收藏+推荐,谢谢!
public partial class PagingViewModel : ObservableObject { public PagingViewModel() { PageSizeOptions = new ObservableCollection { 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 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; }
<Window.Resources>
</Window.Resources> <Grid.RowDefinitions> </Grid.RowDefinitions>
<i:Interaction.Behaviors> <be:SelectedItemsBehavior BindableSelectedItems="{Binding SelectedItems,Mode=OneWayToSource}"/> </i:Interaction.Behaviors> <DataGrid.Columns> <DataGridTextColumn.HeaderTemplate> </DataGridTextColumn.HeaderTemplate> <DataGridTextColumn.HeaderTemplate> </DataGridTextColumn.HeaderTemplate> <DataGridTextColumn.HeaderTemplate> </DataGridTextColumn.HeaderTemplate> </DataGrid.Columns>
<pg:PaginationControl x:Name="pageControl" Grid.Row="1" DataContext="{Binding Pagination}" VerticalAlignment="Bottom" Background="#191D2A" Height="40"> </pg:PaginationControl>
public partial class DataGridViewModel :ObservableObject {
public List employees;
[ObservableProperty] ICollectionView collectionView;
[ObservableProperty] string queryKeyword;
[ObservableProperty] IList selectedItems;
[ObservableProperty] private double totalSalary;
[ObservableProperty] public PagingViewModel pagination;
public DataGridViewModel() { Pagination = new PagingViewModel(); Pagination.PageChanged += OnPageChanged; ChangeLanguage("zh-CN"); IEnumerable employees =EmployeeModel.FakeMany(10); this.employees = new List(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) { SelectedLanguage=languageCode; Pagination.Language = 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().Sum(x => ((EmployeeModel)x).Salary); TotalSalary = sum; }
foreach (var item in employees) { item.IsSelected = item.Salary > 15000; } collectionView.Refresh(); }
}
源代码地址:https://gitee.com/chenshibao/wpfdemo.git
如果本文介绍对你有帮助,可以一键四连:点赞+评论+收藏+推荐,谢谢!