WPF+MVVM案例实战(六)- 自定义分页控件实现

在这里插入图片描述

文章目录

  • 1、项目准备
  • 2、功能实现
    • 1、分页控件 DataPager 实现
    • 2、分页控件数据模型与查询行为
    • 3、数据界面实现
  • 3、运行效果
  • 4、源代码获取


1、项目准备

打开项目 Wpf_Examples,新建 PageBarWindow.xaml 界面、PageBarViewModel.cs ,在用户控件库 UserControlLib中创建用户控件 DataPager.xaml 文件 。如下所示:
在这里插入图片描述
注意:如果没有 Wpf_Examples 项目,可以参考 WPF+MVVM案例实战(三)- 动态数字卡片效果实现,里面详细说明了整个项目的创建过程和环境包安装。

2、功能实现

1、分页控件 DataPager 实现

DataPager.xaml 页面代码实现如下:

<UserControl x:Class="UserControlLib.DataPager"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:UserControlLib"x:Name="userControl"mc:Ignorable="d"Height="30"  HorizontalContentAlignment="Right" VerticalContentAlignment="Center"><Grid><Grid.Resources><Style x:Key="NormalTextBlockStyle" TargetType="{x:Type TextBlock}"><Setter Property="TextWrapping" Value="NoWrap" /><Setter Property="VerticalAlignment" Value="Center" /><Setter Property="FontSize" Value="14"></Setter><Setter Property="Foreground" Value="#96bfd6" /></Style><ControlTemplate x:Key="PageButtonTemplate" TargetType="{x:Type Button}"><TextBlock x:Name="textBlock" VerticalAlignment="Center" Text="{TemplateBinding Content}" HorizontalAlignment="Stretch" Cursor="Hand" Foreground="#96bfd6" /><ControlTemplate.Triggers><Trigger Property="IsEnabled" Value="False"><Setter Property="Foreground" TargetName="textBlock" Value="#FF554F4F" /><Setter Property="Cursor" Value="None" /><Setter Property="FontSize" Value="14"></Setter></Trigger></ControlTemplate.Triggers></ControlTemplate><Style x:Key="LabelStyle" TargetType="{x:Type Label}"><Setter Property="VerticalAlignment" Value="Center" /><Setter Property="FontSize" Value="14"></Setter><Setter Property="Foreground" Value="#FFABA5A5" /></Style><Style x:Key="TextBoxStyle" TargetType="{x:Type TextBox}"><Setter Property="HorizontalAlignment" Value="Center" /><Setter Property="HorizontalContentAlignment" Value="Center" /><Setter Property="VerticalAlignment" Value="Center" /><Setter Property="VerticalContentAlignment" Value="Center" /><Setter Property="Background" Value="#FFEAEBEC" /><Setter Property="FontSize" Value="14"></Setter><Setter Property="Foreground" Value="#96bfd6" /><Setter Property="BorderBrush" Value="Transparent" /><Setter Property="BorderThickness" Value="0" /><Setter Property="CharacterCasing" Value="Upper" /><Setter Property="InputMethod.IsInputMethodEnabled" Value="False" /></Style></Grid.Resources><StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" x:Name="Stack_Main"><TextBlock Style="{DynamicResource NormalTextBlockStyle}" Text="共" /><TextBlock Text="{Binding TotalCount, ElementName=userControl}" Style="{DynamicResource NormalTextBlockStyle}" Margin="4,0" /><TextBlock Style="{DynamicResource NormalTextBlockStyle}" Text="行,每页" /><!--<TextBlock Text="{Binding PageSize, ElementName=userControl}" Style="{DynamicResource NormalTextBlockStyle}" Margin="4,0" />--><ComboBox Grid.Column="0" Height="24" VerticalAlignment="Center" x:Name="cboxPageSize"  Padding="0" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"Width="60" Margin="5,0,0,0" SelectedItem="{Binding PageSize, ElementName=userControl,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Cursor="Hand" /><TextBlock Text="行,第" Style="{DynamicResource NormalTextBlockStyle}" /><TextBlock Text="{Binding PageIndex, ElementName=userControl}" Style="{DynamicResource NormalTextBlockStyle}" Margin="4,0,2,0" /><TextBlock Text="/" Style="{DynamicResource NormalTextBlockStyle}" /><TextBlock Text="{Binding PageCount, ElementName=userControl, Mode=OneWay}" Style="{DynamicResource NormalTextBlockStyle}" Margin="2,0,4,0" /><TextBlock Text="页" Style="{DynamicResource NormalTextBlockStyle}" /><Button x:Name="btnFirst" Content="首页" FontSize="14" Template="{DynamicResource PageButtonTemplate}" VerticalAlignment="Center" Margin="10,0,0,0" Click="btnFirst_Click" IsEnabled="{Binding CanGoFirstOrPrev, ElementName=userControl}" /><Button x:Name="btnPrev" Content="上一页" FontSize="14" Template="{DynamicResource PageButtonTemplate}" VerticalAlignment="Center" Margin="10,0,0,0" Click="btnPrev_Click" IsEnabled="{Binding CanGoFirstOrPrev, ElementName=userControl}" /><Button x:Name="btnNext" Content="下一页" FontSize="14" VerticalAlignment="Center" Template="{DynamicResource PageButtonTemplate}" Margin="10,0,10,0" Click="btnNext_Click" IsEnabled="{Binding CanGoLastOrNext, ElementName=userControl}" /></StackPanel></Grid>
</UserControl>

DataPager.cs 后台代码实现如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;namespace UserControlLib
{/// <summary>/// DataPager.xaml 的交互逻辑/// </summary>public partial class DataPager : UserControl, INotifyPropertyChanged{/// <summary>/// 分页前处理的事件,如果设置e.IsCancel=True将取消分页/// </summary>//public event PageChangingRouteEventHandler PageChanging;/ <summary>/ 分页后处理的事件/ </summary>//public event PageChangedRouteEventHandler Closed;public static readonly RoutedEvent PageChangedEvent = EventManager.RegisterRoutedEvent("PageChangedEvent", RoutingStrategy.Bubble,typeof(EventHandler<PageChangedEventArgs>), typeof(DataPager));public delegate void PageChangedRouteEventHandler(object sender, PageChangedEventArgs e);public event RoutedEventHandler PageChanged{add { this.AddHandler(PageChangedEvent, value); }remove { this.RemoveHandler(PageChangedEvent, value); }}//public event Action Closed;public DataPager(){InitializeComponent();BindComBox();}#region 依赖属性--------------------------------------/// <summary>/// 当前页/// </summary>public int PageIndex{get { return (int)GetValue(PageIndexProperty); }set { SetValue(PageIndexProperty, value); }}// Using a DependencyProperty as the backing store for CurrentPage.  This enables animation, styling, binding, etc...public static readonly DependencyProperty PageIndexProperty =DependencyProperty.Register("PageIndex", typeof(int), typeof(DataPager), new UIPropertyMetadata(1, (sender, e) =>{var dp = sender as DataPager;dp.ChangeNavigationButtonState();}));/// <summary>/// 每页显示数据大小/// </summary>public int PageSize{get { return (int)GetValue(PageSizeProperty); }set { SetValue(PageSizeProperty, value); }}// Using a DependencyProperty as the backing store for PageSize.  This enables animation, styling, binding, etc...public static readonly DependencyProperty PageSizeProperty =DependencyProperty.Register("PageSize", typeof(int), typeof(DataPager), new UIPropertyMetadata(20, (sender, e) =>{var dp = sender as DataPager;if (dp == null) return;dp.InitData();dp.OnPageChanging(1);dp.ChangeNavigationButtonState();}));/// <summary>/// 记录数量/// </summary>public int TotalCount{get { return (int)GetValue(TotalCountProperty); }set{SetValue(TotalCountProperty, value);}}// Using a DependencyProperty as the backing store for TotalCount.  This enables animation, styling, binding, etc...public static readonly DependencyProperty TotalCountProperty =DependencyProperty.Register("TotalCount", typeof(int), typeof(DataPager), new UIPropertyMetadata(0, (sender, e) =>{var dp = sender as DataPager;if (dp == null) return;dp.InitData();dp.ChangeNavigationButtonState();}));/// <summary>/// 总页数/// </summary>public int PageCount{get { return (int)GetValue(PageCountProperty); }private set { SetValue(PageCountProperty, value); }}// Using a DependencyProperty as the backing store for PageCount.  This enables animation, styling, binding, etc...public static readonly DependencyProperty PageCountProperty =DependencyProperty.Register("PageCount", typeof(int), typeof(DataPager), new UIPropertyMetadata(1));/// <summary>/// 是否可以点击首页和上一页按钮/// </summary>public bool CanGoFirstOrPrev{get{if (PageIndex <= 1) return false;return true;}}/// <summary>/// 是否可以点击最后页和下一页按钮/// </summary>public bool CanGoLastOrNext{get{if (PageIndex >= PageCount) return false;return true;}}#endregion 依赖属性--------------------------------------#region 下拉列表数据绑定-------------------------public void BindComBox(){List<string> pageSizeList = new List<string> { "20", "50", "100" };cboxPageSize.ItemsSource = pageSizeList;cboxPageSize.SelectedIndex = 0;}#endregion 下拉列表数据绑定-------------------------/// <summary>/// 初始化数据/// </summary>void InitData(){if (this.TotalCount == 0){this.PageCount = 1;}else{this.PageCount = this.TotalCount % this.PageSize > 0 ? (this.TotalCount / this.PageSize) + 1 : this.TotalCount / this.PageSize;}if (this.PageIndex < 1){this.PageIndex = 1;}if (this.PageIndex > this.PageCount){this.PageIndex = this.PageCount;}if (this.PageSize < 1){this.PageSize = 20;}}/// <summary>/// 点击首页按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnFirst_Click(object sender, RoutedEventArgs e){OnPageChanging(1);}/// <summary>/// 点击上一页按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnPrev_Click(object sender, RoutedEventArgs e){OnPageChanging(this.PageIndex - 1);}/// <summary>/// 点击下一页按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnNext_Click(object sender, RoutedEventArgs e){OnPageChanging(this.PageIndex + 1);}/// <summary>/// 点击末页按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnLast_Click(object sender, RoutedEventArgs e){OnPageChanging(this.PageCount);}/// <summary>/// 点击跳转按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnGoTo_Click(object sender, RoutedEventArgs e){int pageIndex = 1;try{//pageIndex = Convert.ToInt32(txtPageIndex.Text);}catch{}finally{OnPageChanging(pageIndex);}}/// <summary>/// 页码更改/// </summary>/// <param name="pageIndex"></param>internal void OnPageChanging(int pageIndex){if (pageIndex < 1) pageIndex = 1;if (pageIndex > this.PageCount) pageIndex = this.PageCount;var newPageIndex = pageIndex;//var eventArgs = new PageChangingEventArgs() { OldPageIndex = oldPageIndex, NewPageIndex = newPageIndex };var eventArgs = new PageChangedEventArgs(PageChangedEvent, this);this.PageIndex = newPageIndex;RaiseEvent(eventArgs);//if (this.Closed != null)//{//    this.Closed();//}//if (!eventArgs.IsCancel)//{//    if (this.Closed != null)//    {//        this.Closed.Invoke();//    }//}}/// <summary>/// 通知导航按钮(首页,上一页,下一页,末页)状态的更改/// </summary>void ChangeNavigationButtonState(){this.NotifyPropertyChanged("CanGoFirstOrPrev");this.NotifyPropertyChanged("CanGoLastOrNext");}#region INotifyPropertyChanged成员public event PropertyChangedEventHandler PropertyChanged;public void NotifyPropertyChanged(string propertyName){if (this.PropertyChanged != null){this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));}}#endregion INotifyPropertyChanged成员private void cboxPageSize_SelectionChanged(object sender, SelectionChangedEventArgs e){this.PageSize = ((System.Collections.Generic.KeyValuePair<int, string>)(cboxPageSize.SelectedItem)).Key;var param = new PageChangedEventArgs(PageChangedEvent, this);RaiseEvent(param);//if (Closed != null)//{//    this.Closed.Invoke();//}}private void TxtPageIndex_PreviewTextInput(object sender, TextCompositionEventArgs e){Regex re = new Regex("[^0-9]+");e.Handled = re.IsMatch(e.Text);}}public class PageChangedEventArgs : RoutedEventArgs{public PageChangedEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source) { }public DataPager dataPager { get; set; }}
}

2、分页控件数据模型与查询行为

在这里插入图片描述PageBarAction.cs 代码实现如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UserControlLib.Models;namespace UserControlLib.Actions
{public class PageBarAction{public static bool GetDataByPage<T>(int pageSize, int pageIndex, List<T> list, T obj) where T : DataModel{var temp = list.FirstOrDefault(t => t.Key == obj.Key);if (temp == null) return false;int index = list.IndexOf(temp);if (index >= pageSize * (pageIndex - 1) && index < pageSize * pageIndex){return true;}else{return false;}}}
}

DataModel.cs 数据模型如下:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows;
using CommunityToolkit.Mvvm.ComponentModel;namespace UserControlLib.Models
{[Serializable]public class DataModel : ObservableObject{private string key = Guid.NewGuid().ToString();/// <summary>/// Key/// </summary>public string Key{get => key;set => SetProperty(ref key, value);}private int order = 0;/// <summary>/// 序号/// </summary>public int Order{get => order;set => SetProperty(ref order, value);}private bool isSelected = false;/// <summary>/// 是否选中/// </summary>public bool IsSelected{get => isSelected;set => SetProperty(ref isSelected, value);}private bool changedEnabled = false;/// <summary>/// 修改使能/// </summary>public bool ChangedEnabled{get => changedEnabled;set => SetProperty(ref changedEnabled, value);}private List<string> errors = new List<string>();/// <summary>/// 错误提示集合/// </summary>public List<string> Errors{get { return errors; }set { errors = value; }}private string error = string.Empty;/// <summary>/// 错误提示,未使用/// </summary>public string Error{get { return error; }set { error = value; }}public string this[string columnName]{get{var vc = new ValidationContext(this, null, null);vc.MemberName = columnName;var res = new List<System.ComponentModel.DataAnnotations.ValidationResult>();var result = this.GetType().GetProperty(columnName).GetValue(this, null);if (res.Count > 0){return string.Join(Environment.NewLine, res.Select(r => r.ErrorMessage).ToArray());}return string.Empty;}}public string GetHashKey(){return Guid.NewGuid().GetHashCode().ToString();}}}

自定义控件样式如下
在这里插入图片描述

3、数据界面实现

这里我们使用 DataGrid 显示数据,用 DataPager 分页控件实现分页控制。

PageBarWindow.xaml 界面代码如下:

<Window x:Class="Wpf_Examples.Views.PageBarWindow"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:Wpf_Examples.Views"xmlns:uc="clr-namespace:UserControlLib;assembly=UserControlLib"DataContext="{Binding Source={StaticResource Locator},Path=PageBar}"mc:Ignorable="d"Title="PageBarWindow" Height="450" Width="800"><Window.Resources><!--DataGrid样式--><Style TargetType="DataGrid" ><!--网格线颜色--><Setter Property="IsReadOnly" Value="True" /><Setter Property="FontSize" Value="16" /><Setter Property="CanUserResizeColumns" Value="False"/><Setter Property="CanUserResizeRows" Value="False"/><Setter Property="AutoGenerateColumns" Value="False" /><Setter Property="CanUserAddRows" Value="False" /><Setter Property="BorderBrush" Value="#FFF5F7F5" /></Style><!--标题栏样式--><Style TargetType="DataGridColumnHeader" ><Setter Property="SnapsToDevicePixels" Value="True" /><Setter Property="MinWidth" Value="0" /><Setter Property="MinHeight" Value="28" /><Setter Property="FontSize" Value="16" /><Setter Property="Cursor" Value="Hand" /><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="DataGridColumnHeader"><Border x:Name="BackgroundBorder" BorderThickness="0,1,0,1" 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="White" Margin="0,0,50,0" VerticalAlignment="Center" RenderTransformOrigin="1,1" /><Rectangle Width="1" Fill="#d6c79b" HorizontalAlignment="Right" Grid.ColumnSpan="1" /></Grid></Border></ControlTemplate></Setter.Value></Setter><Setter Property="Height" Value="25"/></Style><!--行样式触发--><!--背景色改变必须先设置cellStyle 因为cellStyle会覆盖rowStyle样式--><Style  TargetType="DataGridRow"><Setter Property="Background" Value="#F2F2F2" /><Setter Property="Height" Value="25"/><Setter Property="Foreground" Value="Black" /><Style.Triggers><!--隔行换色--><Trigger Property="AlternationIndex" Value="0" ><Setter Property="Background" Value="#e7e7e7" /></Trigger><Trigger Property="AlternationIndex" Value="1" ><Setter Property="Background" Value="#f2f2f2" /></Trigger><Trigger Property="IsMouseOver" Value="True"><Setter Property="Background" Value="LightGray"/><!--<Setter Property="Foreground" Value="White"/>--></Trigger><Trigger Property="IsSelected" Value="True"><Setter Property="Foreground" Value="Black"/></Trigger></Style.Triggers></Style><!--单元格样式触发--><Style 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="Black"/></Trigger></Style.Triggers></Style><Style TargetType="DataGrid" x:Key="DataGridStyle1"><!--  网格线颜色  --><Setter Property="RowHeaderWidth" Value="0" /><Setter Property="BorderThickness" Value="{StaticResource DataGrid.BorderThickness}" /><Setter Property="HeadersVisibility" Value="Column" /><Setter Property="Background" Value="{StaticResource ColumnHeader.Background}" /><Setter Property="BorderBrush" Value="{StaticResource DataGrid.BorderBrush}" /><Setter Property="HorizontalGridLinesBrush" Value="#00E9ECF1" /><Setter Property="VerticalGridLinesBrush" Value="#00E9ECF1" /><Setter Property="UseLayoutRounding" Value="True" /><Setter Property="SnapsToDevicePixels" Value="True" /><Setter Property="AutoGenerateColumns" Value="False" /><Setter Property="CanUserAddRows" Value="False" /><Setter Property="CanUserReorderColumns" Value="False" /><Setter Property="CanUserResizeColumns" Value="False" /><Setter Property="CanUserResizeRows" Value="False" /><Setter Property="CanUserSortColumns" Value="False" /><Setter Property="GridLinesVisibility" Value="None" /><Setter Property="IsReadOnly" Value="True" /><Setter Property="RowHeight" Value="{StaticResource DataGridRow.Height}" /><Setter Property="SelectionMode" Value="Single" /></Style></Window.Resources><Grid><!--当前托盘采集数据列表分页显示面板--><Border Grid.Row="3" BorderThickness="1"
BorderBrush="Gray"
CornerRadius="5" Margin="8"
Background="Transparent"><Grid Margin="5"><Grid.RowDefinitions><RowDefinition Height="*"/><RowDefinition Height="30"/></Grid.RowDefinitions><DataGrid Background="Transparent" HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding ViewSource}" AutoGenerateColumns="false" Margin="2" Style="{StaticResource DataGridStyle1}"><DataGrid.Columns><DataGridTextColumn Binding="{Binding Id}" Header="序号" Width="80"/><DataGridTextColumn Binding="{Binding Name}" Header="姓名" Width="100"/><DataGridTextColumn Binding="{Binding Gender}" Header="性别" Width="80"/><DataGridTextColumn Binding="{Binding Age}" Header="年龄" Width="80"/><DataGridTextColumn Binding="{Binding Email}" Header="邮箱" Width="*"/><DataGridTextColumn Binding="{Binding Phone}" Header="手机号" Width="*"/></DataGrid.Columns></DataGrid><uc:DataPager Grid.Row="1" HorizontalAlignment="Right"  PageIndex="{Binding PageIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" PageSize="{Binding PageSize, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TotalCount="{Binding TotalCount, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/></Grid></Border></Grid>
</Window>

本文把DataGrid 的属性参数提取出来放在全局配置中。如下所示:

 <Application.Resources><ResourceDictionary><!--界面边框--><SolidColorBrush x:Key="Border.BorderBrush" Color="#50F150" /><sys:Double x:Key="DataGridRow.Height">33</sys:Double><!--  表格外边框线粗细,一般不修改  --><Thickness x:Key="DataGrid.BorderThickness" Bottom="1" Left="1" Right="1" Top="1"/><!--  行边框粗细,一般不修改  --><Thickness x:Key="DataGridRow.BorderThickness" Bottom="0" Left="0" Right="0" Top="1"/><!--  表格外边框颜色  --><SolidColorBrush x:Key="DataGrid.BorderBrush" Color="#E9ECF1" /><!--  列头背景色  --><SolidColorBrush x:Key="ColumnHeader.Background" Color="#F6F7FB" /><!--  列头边框颜色  --><SolidColorBrush x:Key="ColumnHeader.BorderBrush" Color="#E9ECF1" /><vm:ViewModelLocator xmlns:vm="clr-namespace:Wpf_Examples.ViewModels" x:Key="Locator"></vm:ViewModelLocator></ResourceDictionary></Application.Resources>

PageBarViewModel.cs 代码实现如下:

using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using Wpf_Examples.Models;namespace Wpf_Examples.ViewModels
{public class PageBarViewModel:ObservableObject{#region 字段public ICollectionView ViewSource { set; get; }int showDataCount = 0;#endregion#region 属性/// <summary>/// 分页页序号/// </summary>private int pageIndex = 1;public int PageIndex{get { return pageIndex; }set { SetProperty(ref pageIndex, value); RefreshView(); }}/// <summary>/// 分页每页显示数据条数/// </summary>private int pageSize;public int PageSize{get { return pageSize; }set { SetProperty(ref pageSize, value); RefreshView(); }}/// <summary>/// 总显示数据条数/// </summary>private int totalCount = 0;public int TotalCount{get { return totalCount; }set { SetProperty(ref totalCount, value); }}/// <summary>/// 需要显示的数据集合/// </summary>private ObservableCollection<DataInfoListModel> dataInfoList = new ObservableCollection<DataInfoListModel>();public ObservableCollection<DataInfoListModel> DataInfoList{get { return dataInfoList; }set { SetProperty(ref dataInfoList, value); }}#endregionpublic PageBarViewModel(){Random random = new Random();for (int i = 0; i < 30; i++){DataInfoListModel dataInfoListModel = new DataInfoListModel();dataInfoListModel.Order = (i + 1);dataInfoListModel.Id = (i + 1); dataInfoListModel.Name = "测试"+(i+1)+"号";dataInfoListModel.Gender = "男";dataInfoListModel.Age = random.Next(10,80);dataInfoListModel.Phone = "17455861459";dataInfoListModel.Email = "1453849257@qq.com";DataInfoList.Add(dataInfoListModel);}TotalCount = DataInfoList.Count;ViewSource = CollectionViewSource.GetDefaultView(DataInfoList);ViewSource.Filter = new Predicate<object>(OnFilterMovie);}private void RefreshView(){showDataCount = 0;ViewSource.Refresh();}/// <summary>/// 数据过滤器/// </summary>/// <param name="obj"></param>/// <returns></returns>private bool OnFilterMovie(object obj){if (DataInfoList.Count == 0) return false;if (showDataCount >= pageSize) return false;if (!(obj is DataInfoListModel info)) return false;bool flag = UserControlLib.Actions.PageBarAction.GetDataByPage(pageSize, PageIndex, DataInfoList.ToList(), info);if (flag) showDataCount++;return flag;}}
}

3、运行效果

在这里插入图片描述

4、源代码获取

CSDN下载链接:WPF+MVVM案例实战(六)- 自定义分页控件实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/457184.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电池的主被动均衡

只有串联的电池需要进行电压均衡&#xff0c;并联的电池由于电压一致&#xff0c;所以并不需要进行均衡&#xff1a; 被动均衡有一个很明显的特征就是会看到很多大电阻&#xff0c;串联在MOS和电池之间&#xff1a;下图中的保护板就是被动均衡板子以及它的原理图&#xff1a; …

软硬件开发面试问题大汇总篇——针对非常规八股问题的提问与应答

软硬件开发&#xff0c;从微控制器编程到复杂的嵌入式系统开发&#xff0c;离不开下位机、操作系统、上位机等&#xff0c;涵盖范围很广。 如何快速一行代码操作硬件寄存器 直接操作硬件寄存器的代码通常依赖于特定平台和编程语言。在 C 或 C 中&#xff0c;常见的方法是使用指…

WORFBENCH:一个创新的评估基准,目的是全面测试大型语言模型在生成复杂工作流 方面的性能。

2024-10-10,由浙江大学和阿里巴巴集团联合创建的WORFBENCH&#xff0c;一个用于评估大型语言模型&#xff08;LLMs&#xff09;生成工作流能力的基准测试。它包含了一系列的测试和评估协议&#xff0c;用于量化和分析LLMs在处理复杂任务时分解问题和规划执行步骤的能力。WORFBE…

智慧停车场导航系统架构及反向寻车系统解决方案

一、系统概述&#xff1a; 随着当前室内定位导航技术在大型公共场所如政务中心、商业综合体、车站中的应用越来越多&#xff0c;人们对智慧停车场的需求也日益凸显出来&#xff0c;并且智慧停车场对大型公共场所智慧化的整体建设起到重要作用。如何更有效提高停车效率&#xf…

如何加密电脑磁盘?电脑本地磁盘加密方法介绍

随着信息技术的不断发展&#xff0c;电脑磁盘加密已经成为保护个人隐私和数据安全的重要手段。本文将介绍几种常见的电脑本地磁盘加密方法&#xff0c;帮助用户保护自己的数据安全。 文件夹只读加密专家 文件夹只读加密专家不仅可以加密电脑中的文件夹&#xff0c;还可以加密保…

Android 13 SystemUI 隐藏下拉快捷面板部分模块(wifi,bt,nfc等)入口

frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java createTileInternal(tileSpec)方法注释想隐藏的模块即可。

【C++进阶篇】——STL的简介

【C进阶篇】——STL的简介 1.什么是STL STL(standard template libaray-标准模板库)&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架。 2.STL的版本 原始版本 Alexander Stepanov、Meng Lee 在…

redis集群配置

一、Redis集群的三种方式 Redis集群提供了三种分布式方案&#xff1a;主从模式&#xff1a;一个主节点和一个或多个从节点&#xff0c;主节点负责写操作&#xff0c;从节点负责读操作&#xff0c;实现读写分离&#xff0c;分担主节点的压力。哨兵模式&#xff1a;哨兵系统用于监…

【每日一题】LeetCode - 盛最多水的容器

给定一个长度为 n 的整数数组 height。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i])。要求找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 输入示例&#xff1a; height [1,8,6,2,5,4,8,3,7]输出&#xff1a; 4…

Python依赖库的几种离线安装方法

Python依赖库的几种安装方法 python经常需要安装一些依赖库&#xff0c;但是有时候环境可以连通python源&#xff0c;有时不能连通需要离线安装&#xff08;安装单个库包或者整个库环境&#xff09;&#xff0c;使用pip的如下方法可以相对简单解决问题。 一、如何copy一个pyt…

Linux 端口占用 kill被占用的端口 杀掉端口

1、yum install lsof 2、输入netstat -tln,查看系统当前所有被占用端口 3、根据端口查询进程,输入lsof -i :9555,切记不要忘了添加冒号 4、 既然知道进程号了,那杀死当前进程就简单多了,直接 kill -9 PID 回车

如何通过企业架构蓝图引导企业实现数字化转型:构建与实施的全方位指南

在当今迅速变化的商业环境中&#xff0c;企业进行数字化转型已成为提升竞争力、优化运营的必要手段。企业架构蓝图&#xff08;EA Blueprint&#xff09;作为指导企业数字化转型的战略工具&#xff0c;不仅提供了系统化的设计和规划路径&#xff0c;还帮助企业在技术与业务目标…

【读书笔记·VLSI电路设计方法解密】问题26:什么是漏电流问题

功耗现已成为半导体行业面临的主要技术难题。在当前基于CMOS的VLSI电路中,有两种主要的功耗来源:动态功耗和静态功耗。动态功耗来源于晶体管的切换以及芯片上数百万逻辑门输出端的电容反复充电和放电,是芯片为产生有效输出所消耗的能量。静态功耗则指即使在晶体管关闭时也会…

法治在沃刷积分-刷文章浏览数

最近有一个任务&#xff0c;需要通过浏览文章来获取积分&#xff0c;一个个手点文章太麻烦&#xff0c;专业的事情还得专业的来。 法1&#xff1a;模拟发包 抓包发现&#xff0c;是通过接口来使积分增长&#xff0c;那直接模拟发包即可。 至于info_id的获取&#xff0c;可以通…

2024年全球 MoonBit 编程创新赛-零基础早鸟教程-使用wasm4八小时开发井子棋小游戏

前言 本篇文章主要分享 “2024年全球 MoonBit 编程创新赛 游戏赛道”参赛过程中九宫棋游戏的开发技巧和心得。以此抛砖引玉。首先介绍下 MoonBit。 月兔语言 MoonBit 是一个用于云计算和边缘计算的 WebAssembly 端到端的编程语言工具链。 您可以访问 https://try.moonbitlang.…

文本预处理操作简述

自然语言处理 (NLP) 是数据科学的一个分支&#xff0c;主要处理文本数据。除了数值数据外&#xff0c;文本数据也广泛可用&#xff0c;用于分析和解决业务问题。然而&#xff0c;在使用数据进行分析或预测之前&#xff0c;处理数据非常重要。 我们执行文本预处理来准备用于模型…

mysql的卸载与安装

一、mysql的卸载 1、用管理员模式的打开cmd&#xff0c;我的服务名是mysql。 net stop 【你的服务名】 sc delete 【你的服务名】 2、将下图中有包含‘bin’目录&#xff0c;‘data’目录等等的这个总目录删掉 如图我的目录是&#xff1a;mysql-5.7.28-winx64 3、删除mysql的隐…

代码随想录算法训练营Day39 | 卡玛网-46.携带研究材料、416. 分割等和子集

目录 卡玛网-46.携带研究材料 416. 分割等和子集 卡玛网-46.携带研究材料 题目 卡玛网46. 携带研究材料&#xff08;第六期模拟笔试&#xff09; 题目描述&#xff1a; 小明是一位科学家&#xff0c;他需要参加一场重要的国际科学大会&#xff0c;以展示自己的最新研究成…

day3:管道,解压缩,vim

一&#xff0c;管道&#xff08;|&#xff09; 引入 当我们要将本次命令结果作为下次命令参数时就可以用到&#xff0c;极大的简化了操作。 比如&#xff1a;head -5 文件| tail -1&#xff1a;表示显示第五行这就是管道的魅力 概述 管道符&#xff1a;| 作用&#xff1a…

【论文阅读】ESRGAN+

学习资料 论文题目&#xff1a;进一步改进增强型超分辨率生成对抗网络&#xff08;ESRGAN : FURTHER IMPROVING ENHANCED SUPER-RESOLUTION GENERATIVE ADVERSARIAL NETWORK&#xff09;论文地址&#xff1a;2001.08073代码&#xff1a;ncarraz/ESRGANplus&#xff1a; ICASSP …