<UserControl.Resources>
</UserControl.Resources>
<ItemsControl.ItemsPanel> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate> 1.2 分页控件的ViewModel:Paging2ViewModel public partial class Paging2ViewModel : ObservableObject { private int _totalItems; private int _itemsPerPage = 10; private int _currentPage = 1; private int _maxVisiblePages = 7; [ObservableProperty] private ObservableCollection pageSizeOptions; //[ObservableProperty] //private int pageSize; [ObservableProperty] private string language; public int TotalItems { get => _totalItems; set { SetProperty(ref _totalItems, value); UpdatePagination(); } } public int ItemsPerPage { get => _itemsPerPage; set { SetProperty(ref _itemsPerPage, value); UpdatePagination(); } } public int CurrentPage { get => _currentPage; set { SetProperty(ref _currentPage, value); UpdatePagination(); } } public ObservableCollection PageNumbers { get; set; } = new(); public ICommand NextPageCommand => new RelayCommand(() => { if (CurrentPage < TotalPages) CurrentPage++; PageChanged.Invoke(CurrentPage, ItemsPerPage); }); public ICommand PreviousPageCommand => new RelayCommand(() => { if (CurrentPage > 1) CurrentPage--; PageChanged.Invoke(CurrentPage, ItemsPerPage); }); public ICommand GoToPageCommand => new RelayCommand(page => { if (page != CurrentPage) CurrentPage = page; PageChanged.Invoke(CurrentPage, ItemsPerPage); }); public ICommand CurrentPageChangedCommand { get; set; } public int TotalPages => (int)Math.Ceiling((double)TotalItems / ItemsPerPage); public bool CanGoNext => CurrentPage < TotalPages; public bool CanGoPrevious => CurrentPage > 1; public string SummaryText => Language == "zh-CN" ? $"共 {TotalItems} 条 / {TotalPages} 页" : $"total {TotalItems} items / {TotalPages} pages"; public Paging2ViewModel() { Language = "zh-CN"; PageSizeOptions = new ObservableCollection { 10, 20, 50 }; ItemsPerPage = PageSizeOptions[0]; CurrentPage = 1; UpdatePagination(); } private void UpdatePagination() { PageNumbers.Clear(); int totalPages = TotalPages; if (totalPages <= _maxVisiblePages) { for (int i = 1; i <= totalPages; i++) AddPageButton(i); } else { AddPageButton(1); if (CurrentPage > 4) AddEllipsis(); int start = Math.Max(2, CurrentPage - 1); int end = Math.Min(totalPages - 1, CurrentPage + 1); for (int i = start; i <= end; i++) AddPageButton(i); if (CurrentPage < totalPages - 3) AddEllipsis(); AddPageButton(totalPages); } CurrentPageChangedCommand?.Execute(CurrentPage); OnPropertyChanged(nameof(SummaryText)); OnPropertyChanged(nameof(CanGoNext)); OnPropertyChanged(nameof(CanGoPrevious)); } private void AddPageButton(int number) { PageNumbers.Add(new PaginationPageNumber { Display = number.ToString(), PageNumber = number, IsEnabled = number != CurrentPage }); } private void AddEllipsis() { PageNumbers.Add(new PaginationPageNumber { Display = "...", PageNumber = -1, IsEnabled = false }); } //partial void OnPageSizeChanged(int value) //{ // CurrentPage = 1; // OnPropertyChanged(nameof(TotalPages)); // OnPropertyChanged(nameof(SummaryText)); // //GoToPageCommand(CurrentPage); // UpdatePagination(); //} partial void OnLanguageChanged(string value) { OnPropertyChanged(nameof(SummaryText)); } public event Action<int, int> PageChanged; } public class PaginationPageNumber { public string Display { get; set; } // "1", "...", "5" 等 public int PageNumber { get; set; } public bool IsEnabled { get; set; } = true; } 2.DataGridAndPageView 界面展示如下: 2.1 UI界面如下: <WindowChrome.WindowChrome> </WindowChrome.WindowChrome> <Window.Resources> </Window.Resources> <Grid.RowDefinitions> </Grid.RowDefinitions>
<ItemsControl.ItemsPanel> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate>
public partial class Paging2ViewModel : ObservableObject { private int _totalItems; private int _itemsPerPage = 10; private int _currentPage = 1; private int _maxVisiblePages = 7;
[ObservableProperty] private ObservableCollection pageSizeOptions;
//[ObservableProperty] //private int pageSize;
[ObservableProperty] private string language;
public int TotalItems { get => _totalItems; set { SetProperty(ref _totalItems, value); UpdatePagination(); } }
public int ItemsPerPage { get => _itemsPerPage; set { SetProperty(ref _itemsPerPage, value); UpdatePagination(); } }
public int CurrentPage { get => _currentPage; set { SetProperty(ref _currentPage, value); UpdatePagination(); } }
public ObservableCollection PageNumbers { get; set; } = new();
public ICommand NextPageCommand => new RelayCommand(() => { if (CurrentPage < TotalPages) CurrentPage++; PageChanged.Invoke(CurrentPage, ItemsPerPage); });
public ICommand PreviousPageCommand => new RelayCommand(() => { if (CurrentPage > 1) CurrentPage--; PageChanged.Invoke(CurrentPage, ItemsPerPage); });
public ICommand GoToPageCommand => new RelayCommand(page => { if (page != CurrentPage) CurrentPage = page; PageChanged.Invoke(CurrentPage, ItemsPerPage); });
public ICommand CurrentPageChangedCommand { get; set; }
public int TotalPages => (int)Math.Ceiling((double)TotalItems / ItemsPerPage);
public bool CanGoNext => CurrentPage < TotalPages; public bool CanGoPrevious => CurrentPage > 1;
public string SummaryText => Language == "zh-CN" ? $"共 {TotalItems} 条 / {TotalPages} 页" : $"total {TotalItems} items / {TotalPages} pages";
public Paging2ViewModel() { Language = "zh-CN"; PageSizeOptions = new ObservableCollection { 10, 20, 50 }; ItemsPerPage = PageSizeOptions[0]; CurrentPage = 1; UpdatePagination(); }
private void UpdatePagination() { PageNumbers.Clear(); int totalPages = TotalPages;
if (totalPages <= _maxVisiblePages) { for (int i = 1; i <= totalPages; i++) AddPageButton(i); } else { AddPageButton(1);
if (CurrentPage > 4) AddEllipsis();
int start = Math.Max(2, CurrentPage - 1); int end = Math.Min(totalPages - 1, CurrentPage + 1);
for (int i = start; i <= end; i++) AddPageButton(i);
if (CurrentPage < totalPages - 3) AddEllipsis();
AddPageButton(totalPages); }
CurrentPageChangedCommand?.Execute(CurrentPage); OnPropertyChanged(nameof(SummaryText)); OnPropertyChanged(nameof(CanGoNext)); OnPropertyChanged(nameof(CanGoPrevious)); }
private void AddPageButton(int number) { PageNumbers.Add(new PaginationPageNumber { Display = number.ToString(), PageNumber = number, IsEnabled = number != CurrentPage }); }
private void AddEllipsis() { PageNumbers.Add(new PaginationPageNumber { Display = "...", PageNumber = -1, IsEnabled = false }); }
//partial void OnPageSizeChanged(int value) //{ // CurrentPage = 1; // OnPropertyChanged(nameof(TotalPages)); // OnPropertyChanged(nameof(SummaryText)); // //GoToPageCommand(CurrentPage); // UpdatePagination(); //}
partial void OnLanguageChanged(string value) { OnPropertyChanged(nameof(SummaryText)); }
public event Action<int, int> PageChanged; }
public class PaginationPageNumber { public string Display { get; set; } // "1", "...", "5" 等 public int PageNumber { get; set; } public bool IsEnabled { get; set; } = true; }
<WindowChrome.WindowChrome> </WindowChrome.WindowChrome>
<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:Pagination2Control x:Name="pageControl" Grid.Row="2" DataContext="{Binding Pagination}" VerticalAlignment="Bottom" Background="#191D2A" Height="40"> </pg:Pagination2Control> <i:Interaction.Triggers> <i:EventTrigger EventName="SelectionChanged"> <i:InvokeCommandAction Command="{Binding ChangeLanguageCommand}" CommandParameter="{Binding SelectedValue, RelativeSource={RelativeSource AncestorType=ComboBox}}" /> </i:EventTrigger> </i:Interaction.Triggers> 2.2 实现DataGridAndPageViewModel的业务逻辑: public partial class DataGridAndPageViewModel: ObservableObject { public List employees; [ObservableProperty] ICollectionView collectionView; [ObservableProperty] string queryKeyword; [ObservableProperty] IList selectedItems; [ObservableProperty] private double totalSalary; [ObservableProperty] public Paging2ViewModel pagination; public ObservableCollection Languages { get; } = new ObservableCollection { new LanguageItem { Tag = "zh-CN", Name = "中文" }, new LanguageItem { Tag = "en", Name = "英文" } }; [ObservableProperty] private string selectedLanguage; public ICommand CloseCommand { get; } public DataGridAndPageViewModel() { Pagination = new Paging2ViewModel(); 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.ItemsPerPage) .Take(Pagination.ItemsPerPage) .Select((e, i) => { e.Index = (Pagination.CurrentPage - 1) * Pagination.ItemsPerPage + i + 1; return e; }).ToList(); CollectionView = CollectionViewSource.GetDefaultView(pageData); Pagination.TotalItems = this.employees.Count; CloseCommand = new RelayCommand(() => { // 发送关闭窗口的消息 WeakReferenceMessenger.Default.Send(new CloseWindowMessage("DataGridAndPageView")); }); } partial void OnQueryKeywordChanged(string value) { Pagination.CurrentPage = 1; // 筛选后回到第一页 OnPageChanged(Pagination.CurrentPage, Pagination.ItemsPerPage); } [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; } 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] public void Add() { employees.Add(EmployeeModel.FakeOne()); OnPageChanged(Pagination.CurrentPage, Pagination.ItemsPerPage); } [RelayCommand] public void Delete() { if (SelectedItems != null) { employees.RemoveAll(e => SelectedItems.Contains(e)); OnPageChanged(Pagination.CurrentPage, Pagination.ItemsPerPage); } } [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.运行效果如下: 分页显示 超过7页后,显示“....”: 源代码地址:https://gitee.com/chenshibao/wpfdemo.git 如果本文介绍对你有帮助,可以一键四连:点赞+评论+收藏+推荐,谢谢!
public partial class DataGridAndPageViewModel: ObservableObject { public List employees;
[ObservableProperty] ICollectionView collectionView;
[ObservableProperty] string queryKeyword;
[ObservableProperty] IList selectedItems;
[ObservableProperty] private double totalSalary;
[ObservableProperty] public Paging2ViewModel pagination;
public ObservableCollection Languages { get; } = new ObservableCollection { new LanguageItem { Tag = "zh-CN", Name = "中文" }, new LanguageItem { Tag = "en", Name = "英文" } };
[ObservableProperty] private string selectedLanguage;
public ICommand CloseCommand { get; } public DataGridAndPageViewModel() { Pagination = new Paging2ViewModel(); 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.ItemsPerPage) .Take(Pagination.ItemsPerPage) .Select((e, i) => { e.Index = (Pagination.CurrentPage - 1) * Pagination.ItemsPerPage + i + 1; return e; }).ToList();
CollectionView = CollectionViewSource.GetDefaultView(pageData);
Pagination.TotalItems = this.employees.Count;
CloseCommand = new RelayCommand(() => { // 发送关闭窗口的消息 WeakReferenceMessenger.Default.Send(new CloseWindowMessage("DataGridAndPageView")); }); }
partial void OnQueryKeywordChanged(string value) { Pagination.CurrentPage = 1; // 筛选后回到第一页 OnPageChanged(Pagination.CurrentPage, Pagination.ItemsPerPage); }
[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; }
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();
}
[RelayCommand] public void Add() { employees.Add(EmployeeModel.FakeOne()); OnPageChanged(Pagination.CurrentPage, Pagination.ItemsPerPage); }
[RelayCommand] public void Delete() { if (SelectedItems != null) { employees.RemoveAll(e => SelectedItems.Contains(e)); OnPageChanged(Pagination.CurrentPage, Pagination.ItemsPerPage); } }
[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(); }
分页显示
超过7页后,显示“....”:
源代码地址:https://gitee.com/chenshibao/wpfdemo.git
如果本文介绍对你有帮助,可以一键四连:点赞+评论+收藏+推荐,谢谢!