WPF简单的分页控件实现
XAML代码(使用ItemsControl控件实现):
<UserControl x:Class="SunCreate.Vipf.Client.UI.CityDoor.PageControl" 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" mc:Ignorable="d" d:DesignHeight="28" d:DesignWidth="450"> <Grid> <StackPanel Orientation="Horizontal" VerticalAlignment="Center"> <!--上一页--> <Button x:Name="btnPrePage" Height="28" Background="Transparent" Foreground="#fff" Click="btnPrePage_Click" CommandParameter="{Binding}" VerticalAlignment="Center" Visibility="{Binding NumVisible}"> <Button.Template> <ControlTemplate> <Border x:Name="border" Background="Transparent" CornerRadius="2"> <TextBlock x:Name="txt" Margin="10 0 10 1" Foreground="{TemplateBinding Foreground}" FontSize="{Binding FontSize}" FontWeight="Bold" Text="<<" VerticalAlignment="Center"></TextBlock> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter TargetName="border" Property="Background" Value="#6633ccee"></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Button.Template> </Button> <!--页码--> <ItemsControl x:Name="itemsControl"> <ItemsControl.Template> <ControlTemplate> <ItemsPresenter></ItemsPresenter> </ControlTemplate> </ItemsControl.Template> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal"></StackPanel> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Grid> <Button x:Name="btnNum" Height="28" Background="Transparent" Click="btnNum_Click" CommandParameter="{Binding}" VerticalAlignment="Center" Visibility="{Binding NumVisible}"> <Button.Template> <ControlTemplate> <Border x:Name="border" Background="Transparent" CornerRadius="2" SnapsToDevicePixels="True"> <TextBlock x:Name="txt" Margin="10 0 10 0" Foreground="{Binding CurrentPageColor}" FontSize="{Binding FontSize}" FontWeight="Bold" Text="{Binding Page}" VerticalAlignment="Center" ></TextBlock> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter TargetName="border" Property="Background" Value="#6633ccee"></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Button.Template> </Button> <Border Height="28" Visibility="{Binding OmitVisible}"> <TextBlock x:Name="txt" Margin="10 0 10 3" Foreground="#fff" FontSize="{Binding FontSize}" Text="…" VerticalAlignment="Center" ></TextBlock> </Border> </Grid> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> <!--下一页--> <Button x:Name="btnNextPage" Height="28" Background="Transparent" Foreground="#fff" Click="btnNextPage_Click" CommandParameter="{Binding}" VerticalAlignment="Center" Visibility="{Binding NumVisible}"> <Button.Template> <ControlTemplate> <Border x:Name="border" Background="Transparent" CornerRadius="2"> <TextBlock x:Name="txt" Margin="10 0 10 1" Foreground="{TemplateBinding Foreground}" FontSize="{Binding FontSize}" FontWeight="Bold" Text=">>" VerticalAlignment="Center"></TextBlock> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter TargetName="border" Property="Background" Value="#6633ccee"></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Button.Template> </Button> </StackPanel> </Grid> </UserControl>
后台代码:
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; 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 SunCreate.Vipf.Client.UI.CityDoor { /// <summary> /// 分页控件 /// </summary> public partial class PageControl : UserControl, INotifyPropertyChanged { #region 事件 /// <summary> /// 分页事件 /// </summary> public event EventHandler<PageChangedEventArgs> PageChanged; #endregion #region 变量 private ObservableCollection<PageControlItemModel> _collection = new ObservableCollection<PageControlItemModel>(); private List<PageControlItemModel> _list = null; #endregion #region 属性 private int _FontSize = 12; /// <summary> /// 文字字体大小 /// </summary> public int FontSize { get { return _FontSize; } set { _FontSize = value; OnPropertyChanged("FontSize"); CalcPageNumList(); //计算页码 } } #endregion #region 分页相关属性 private int _PageCount = 1; /// <summary> /// 总页数 /// </summary> public int PageCount { get { return _PageCount; } set { _PageCount = value; OnPropertyChanged("PageCount"); } } private int _Page = 1; /// <summary> /// 当前页码 /// </summary> public int Page { get { return _Page; } set { _Page = value; OnPropertyChanged("Page"); CalcPageNumList(); //计算页码 } } private int _RecordCount = 0; /// <summary> /// 记录总数 /// </summary> public int RecordCount { get { return _RecordCount; } set { _RecordCount = value; OnPropertyChanged("RecordCount"); CalcPageNumList(); //计算页码 } } private int _PageSize = 10; /// <summary> /// 每页记录数 /// </summary> public int PageSize { get { return _PageSize; } set { _PageSize = value; OnPropertyChanged("PageSize"); CalcPageNumList(); //计算页码 } } private int _ContinuousCount = 3; /// <summary> /// 当前页码右边连续页码数 /// </summary> public int ContinuousCount { get { return _ContinuousCount; } set { _ContinuousCount = value; OnPropertyChanged("_ContinuousCount"); CalcPageNumList(); //计算页码 } } #endregion #region 构造函数 public PageControl() { InitializeComponent(); this.itemsControl.ItemsSource = _collection; } #endregion #region 单击页码事件 private void btnNum_Click(object sender, RoutedEventArgs e) { if (PageChanged != null) { Button btn = sender as Button; PageControlItemModel itemModel = btn.CommandParameter as PageControlItemModel; if (itemModel.Page != Page) { Page = itemModel.Page; CalcPageNumList(); PageChangedEventArgs args = new PageChangedEventArgs(itemModel.Page); PageChanged(sender, args); } } } #endregion #region 计算页码 /// <summary> /// 计算页码 /// </summary> private void CalcPageNumList() { PageCount = (RecordCount - 1) / PageSize + 1; //计算总页数PageCount _list = new List<PageControlItemModel>(); //第一页 PageControlItemModel item = new PageControlItemModel(1, Page); _list.Add(item); //当前页码连续页码 for (int i = Page - ContinuousCount; i <= Page + ContinuousCount; i++) { if (i > 0 && i < PageCount) { item = new PageControlItemModel(i, Page); if (!_list.Exists(a => a.Page == item.Page)) { _list.Add(item); } } } //最后一页 item = new PageControlItemModel(PageCount, Page); if (!_list.Exists(a => a.Page == item.Page)) { _list.Add(item); } for (int i = _list.Count - 1; i > 0; i--) { if (_list[i].Page - _list[i - 1].Page > 1) { _list.Insert(i, new PageControlItemModel(0, Page, 2)); } } //上一页下一页 if (Page == 1) { this.btnPrePage.IsEnabled = false; this.btnPrePage.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#88dddddd")); } else { this.btnPrePage.IsEnabled = true; this.btnPrePage.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#fff")); } if (Page == PageCount) { this.btnNextPage.IsEnabled = false; this.btnNextPage.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#88dddddd")); } else { this.btnNextPage.IsEnabled = true; this.btnNextPage.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#fff")); } _collection.Clear(); _list.ForEach(a => { _collection.Add(a); }); } #endregion #region 上一页 private void btnPrePage_Click(object sender, RoutedEventArgs e) { int prePage = Page - 1; if (prePage < 1) prePage = 1; if (prePage != Page) { Page = prePage; CalcPageNumList(); PageChangedEventArgs args = new PageChangedEventArgs(prePage); PageChanged(sender, args); } } #endregion #region 下一页 private void btnNextPage_Click(object sender, RoutedEventArgs e) { int nextPage = Page + 1; if (nextPage > PageCount) nextPage = PageCount; if (nextPage != Page) { Page = nextPage; CalcPageNumList(); PageChangedEventArgs args = new PageChangedEventArgs(nextPage); PageChanged(sender, args); } } #endregion #region INotifyPropertyChanged接口 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string name) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(name)); } } #endregion } #region 分页控件Item Model /// <summary> /// 分页控件Item Model /// </summary> public class PageControlItemModel : INotifyPropertyChanged { private int _Type = 1; /// <summary> /// 类型(1数字 2省略号) /// </summary> public int Type { get { return _Type; } set { _Type = value; OnPropertyChanged("Type"); if (_Type == 1) { NumVisible = Visibility.Visible; OmitVisible = Visibility.Collapsed; } else { NumVisible = Visibility.Collapsed; OmitVisible = Visibility.Visible; } } } private bool _IsCurrentPage; /// <summary> /// 是否当前页码 /// </summary> public bool IsCurrentPage { get { return _IsCurrentPage; } set { _IsCurrentPage = value; OnPropertyChanged("IsCurrentPage"); if (_IsCurrentPage) { CurrentPageColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#00f0ff")); } else { CurrentPageColor = new SolidColorBrush(Colors.White); } } } private SolidColorBrush _CurrentPageColor = new SolidColorBrush(Colors.White); /// <summary> /// 当前页码颜色 /// </summary> public SolidColorBrush CurrentPageColor { get { return _CurrentPageColor; } set { _CurrentPageColor = value; OnPropertyChanged("CurrentPageColor"); } } private int _Page; /// <summary> /// 页码 /// </summary> public int Page { get { return _Page; } set { _Page = value; OnPropertyChanged("Page"); } } private Visibility _NumVisible = Visibility.Visible; /// <summary> /// 数字可见 /// </summary> public Visibility NumVisible { get { return _NumVisible; } set { _NumVisible = value; OnPropertyChanged("NumVisible"); } } private Visibility _OmitVisible = Visibility.Collapsed; /// <summary> /// 省略号可见 /// </summary> public Visibility OmitVisible { get { return _OmitVisible; } set { _OmitVisible = value; OnPropertyChanged("OmitVisible"); } } /// <summary> /// 分页控件Item Model /// </summary> /// <param name="page">页码</param> /// <param name="currentPage">当前页码</param> /// <param name="type">类型(1数字 2省略号)</param> public PageControlItemModel(int page, int currentPage, int type = 1) { Type = type; Page = page; IsCurrentPage = page == currentPage; } #region INotifyPropertyChanged接口 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string name) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(name)); } } #endregion } #endregion #region 分页事件参数 /// <summary> /// 分页事件参数 /// </summary> public class PageChangedEventArgs : EventArgs { private int _Page = 1; /// <summary> /// 当前页码 /// </summary> public int Page { get { return _Page; } } /// <summary> /// 分页事件参数 /// </summary> /// <param name="page">当前页码</param> public PageChangedEventArgs(int page) { _Page = page; } } #endregion }
效果图:
如何使用:
前端代码:
<cityDoor:PageControl x:Name="pageControl" Grid.Row="2" Margin="0 0 0 23" PageChanged="PageControl_PageChanged" HorizontalAlignment="Center" VerticalAlignment="Center"></cityDoor:PageControl>
后端代码:
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows; using System.Windows.Documents; using System.Windows.Media; using System.Windows.Media.Imaging; namespace SunCreate.Vipf.Client.UI.CityDoor { /// <summary> /// 重点关注对象 /// </summary> public partial class TodayWarningWin : Window { private ObservableCollection<TodayWarningModel> _listAll = new ObservableCollection<TodayWarningModel>(); private ObservableCollection<TodayWarningModel> _currentPageList = new ObservableCollection<TodayWarningModel>(); public TodayWarningWin() { InitializeComponent(); if (DesignerProperties.GetIsInDesignMode(this)) return; this.itemsControl.ItemsSource = _currentPageList; this.pageControl.PageSize = 12; TestData(); GetListPage(1); } #region 分页取数据 private void GetListPage(int currentPage) { this.pageControl.Page = currentPage; this.pageControl.RecordCount = _listAll.Count; int start = (currentPage - 1) * this.pageControl.PageSize; int end = start + this.pageControl.PageSize - 1; _currentPageList.Clear(); for (int i = start; i <= end && i < _listAll.Count; i++) { _currentPageList.Add(_listAll[i]); } } #endregion 分页取数据 #region 测试数据 /// <summary> /// 测试数据 /// </summary> private void TestData() { _listAll.Clear(); Random rnd = new Random(); List<TodayWarningModel> tempList = new List<TodayWarningModel>(); for (int i = 1; i <= 356; i++) { TodayWarningModel model = new TodayWarningModel(); model.Type = rnd.Next(1, 3); model.CarImage = new BitmapImage(new Uri("/SunCreate.Vipf.Client.Resources;component/Image/CityDoor/测试车辆图片.png", UriKind.RelativeOrAbsolute)); model.PersonImage = new BitmapImage(new Uri("/SunCreate.Vipf.Client.Resources;component/Image/CityDoor/测试人员图片.png", UriKind.RelativeOrAbsolute)); model.PersonImageCompare = new BitmapImage(new Uri("/SunCreate.Vipf.Client.Resources;component/Image/CityDoor/测试人员图片.png", UriKind.RelativeOrAbsolute)); model.CarNum = "皖AD1235"; model.CarVisible = rnd.Next(1, 3) == 1 ? Visibility.Visible : Visibility.Collapsed; if (model.CarVisible == Visibility.Collapsed) model.PersonVisible = Visibility.Visible; model.Place = "繁华大道与祝融路交口"; model.PersonName = "张亮"; model.Desc = "三车偷盗库"; model.HandleStatus = "未处理"; model.Status = "在逃"; model.Similar = 80; model.Time = DateTime.Now.AddHours(-1); tempList.Add(model); } tempList.Sort((a, b) => DateTime.Compare(b.Time, a.Time)); tempList.ForEach(item => { _listAll.Add(item); }); } #endregion 测试数据 #region 分页事件 private void PageControl_PageChanged(object sender, PageChangedEventArgs e) { GetListPage(e.Page); } #endregion 分页事件 #region 关闭窗体按钮事件 private void btnClose_Click(object sender, RoutedEventArgs e) { this.Close(); } #endregion 关闭窗体按钮事件 } #region 今日告警Model /// <summary> /// 今日告警Model /// </summary> public class TodayWarningModel : INotifyPropertyChanged { private int _Type; /// <summary> /// 1人 2车 /// </summary> public int Type { get { return _Type; } set { _Type = value; OnPropertyChanged("Type"); if (_Type == 1) { PersonVisible = Visibility.Visible; CarVisible = Visibility.Collapsed; Icon = new BitmapImage(new Uri("/SunCreate.Vipf.Client.Resources;component/Image/CityDoor/人标签.png", UriKind.RelativeOrAbsolute)); } else { PersonVisible = Visibility.Collapsed; CarVisible = Visibility.Visible; Icon = new BitmapImage(new Uri("/SunCreate.Vipf.Client.Resources;component/Image/CityDoor/车标签.png", UriKind.RelativeOrAbsolute)); } } } private string _PersonName; /// <summary> /// 人员姓名 /// </summary> public string PersonName { get { return _PersonName; } set { _PersonName = value; OnPropertyChanged("PersonName"); } } private string _CarNum; /// <summary> /// 车牌号 /// </summary> public string CarNum { get { return _CarNum; } set { _CarNum = value; OnPropertyChanged("CarNum"); } } private string _Status; /// <summary> /// 状态 /// </summary> public string Status { get { return _Status; } set { _Status = value; OnPropertyChanged("Status"); } } private string _Place; /// <summary> /// 地点 /// </summary> public string Place { get { return _Place; } set { _Place = value; OnPropertyChanged("Place"); } } private DateTime _Time; /// <summary> /// 时间 /// </summary> public DateTime Time { get { return _Time; } set { _Time = value; OnPropertyChanged("Time"); TimeString = _Time.ToString("yyyy-MM-dd HH:mm:ss"); } } private string _TimeString; /// <summary> /// 时间 /// </summary> public string TimeString { get { return _TimeString; } set { _TimeString = value; OnPropertyChanged("TimeString"); } } private string _HandleStatus; /// <summary> /// 处理状态 /// </summary> public string HandleStatus { get { return _HandleStatus; } set { _HandleStatus = value; OnPropertyChanged("HandleStatus"); } } private string _Desc; /// <summary> /// 案件描述 /// </summary> public string Desc { get { return _Desc; } set { _Desc = value; OnPropertyChanged("Desc"); } } private int _Similar; /// <summary> /// 相似度 /// </summary> public int Similar { get { return _Similar; } set { _Similar = value; OnPropertyChanged("Similar"); } } private Visibility _PersonVisible; /// <summary> /// 人员告警可见 /// </summary> public Visibility PersonVisible { get { return _PersonVisible; } set { _PersonVisible = value; OnPropertyChanged("PersonVisible"); } } private Visibility _CarVisible; /// <summary> /// 车辆告警可见 /// </summary> public Visibility CarVisible { get { return _CarVisible; } set { _CarVisible = value; OnPropertyChanged("CarVisible"); } } private ImageSource _Icon; /// <summary> /// 图标 /// </summary> public ImageSource Icon { get { return _Icon; } set { _Icon = value; OnPropertyChanged("Icon"); } } private ImageSource _CarImage; /// <summary> /// 车辆图片 /// </summary> public ImageSource CarImage { get { return _CarImage; } set { _CarImage = value; OnPropertyChanged("CarImage"); } } private ImageSource _PersonImage; /// <summary> /// 人员图片 /// </summary> public ImageSource PersonImage { get { return _PersonImage; } set { _PersonImage = value; OnPropertyChanged("PersonImage"); } } private ImageSource _PersonImageCompare; /// <summary> /// 人员图片对比 /// </summary> public ImageSource PersonImageCompare { get { return _PersonImageCompare; } set { _PersonImageCompare = value; OnPropertyChanged("PersonImageCompare"); } } #region INotifyPropertyChanged接口 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string name) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(name)); } } #endregion INotifyPropertyChanged接口 } #endregion 今日告警Model }