WPF自定义翻页控件

XAML文件如下:

XML 复制代码
<UserControl
    x:Class="CTMVVMDemo.View.UserControls.DataPager"
    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:local="clr-namespace:CTMVVMDemo.View.UserControls"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Name="userControl"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">
    <Grid>
        <!--
            一个视图数据源一般情况来自两处:
            1。ViewModel
            2。.cs文件
        -->

        <StackPanel
            HorizontalAlignment="Right"
            VerticalAlignment="Center"
            Orientation="Horizontal">
            <TextBlock Text="共" />
            <TextBlock Margin="4,0" Text="{Binding TotalCount, ElementName=userControl}" />
            <TextBlock Text="条记录,每页" />
            <ComboBox
                Grid.Column="0"
                Width="60"
                Height="24"
                Margin="5,0,0,0"
                Padding="0"
                VerticalAlignment="Center"
                HorizontalContentAlignment="Center"
                VerticalContentAlignment="Center"
                Cursor="Hand"
                ItemsSource="{Binding ElementName=userControl, Path=PageSizes}"
                SelectedItem="{Binding PageSize, ElementName=userControl}" />
            <TextBlock Text="条,第" />
            <TextBlock Margin="4,0,2,0" Text="{Binding PageIndex, ElementName=userControl}" />
            <TextBlock Text="/" />
            <TextBlock Margin="2,0,4,0" Text="{Binding PageCount, ElementName=userControl}" />
            <TextBlock Text="页" />
            <Button
                x:Name="btnFirst"
                Margin="10,0,0,0"
                VerticalAlignment="Center"
                Click="btnFirst_Click"
                Content="首页"
                FontSize="14"
                IsEnabled="{Binding CanGoFirstOrPrev, ElementName=userControl}" />
            <Button
                x:Name="btnPrev"
                Margin="10,0,0,0"
                VerticalAlignment="Center"
                Click="btnPrev_Click"
                Content="上一页"
                FontSize="14"
                IsEnabled="{Binding CanGoFirstOrPrev, ElementName=userControl}" />
            <Button
                x:Name="btnNext"
                Margin="10,0,10,0"
                VerticalAlignment="Center"
                Click="btnNext_Click"
                Content="下一页"
                FontSize="14"
                IsEnabled="{Binding CanGoLastOrNext, ElementName=userControl}" />

            <Button
                x:Name="btnLast"
                Margin="10,0,10,0"
                VerticalAlignment="Center"
                Click="btnLast_Click"
                Content="末页"
                FontSize="14"
                IsEnabled="{Binding CanGoLastOrNext, ElementName=userControl}" />
        </StackPanel>

    </Grid>
</UserControl>

依赖属性的代码如下:

cs 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace CTMVVMDemo.View.UserControls
{
    public partial class DataPager : UserControl, INotifyPropertyChanged
    {
        public DataPager()
        {
            InitializeComponent();
        }

        #region 路由事件
        public static readonly RoutedEvent PageChangedEvent = EventManager.RegisterRoutedEvent(
            "PageChanged",
            RoutingStrategy.Bubble,
            typeof(RoutedEventHandler),
            typeof(DataPager));

        public event RoutedEventHandler PageChanged
        {
            add { AddHandler(PageChangedEvent, value); }
            remove { RemoveHandler(PageChangedEvent, value); }
        }
        #endregion

        #region 依赖属性

        /// <summary>
        /// 当前页
        /// </summary>
        public int PageIndex
        {
            get { return (int)GetValue(PageIndexProperty); }
            set { SetValue(PageIndexProperty, value); }
        }
        public static readonly DependencyProperty PageIndexProperty =
            DependencyProperty.Register(
                "PageIndex",
                typeof(int),
                typeof(DataPager),
                new UIPropertyMetadata(1, (sender, e) =>
                {
                    var dp = sender as DataPager;
                    if (dp == null) return;
                    dp.ChangeNavigationButtonState();
                }));

        /// <summary>
        /// 每页显示条数
        /// </summary>
        public int PageSize
        {
            get { return (int)GetValue(PageSizeProperty); }
            set { SetValue(PageSizeProperty, value); }
        }
        public static readonly DependencyProperty PageSizeProperty =
            DependencyProperty.Register(
                "PageSize",
                typeof(int),
                typeof(DataPager),
                new UIPropertyMetadata(10, (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);
            }
        }
        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); }
        }
        public static readonly DependencyProperty PageCountProperty =
            DependencyProperty.Register("PageCount", typeof(int), typeof(DataPager), new UIPropertyMetadata(1));


        public List<int> PageSizes
        {
            get { return (List<int>)GetValue(PageSizesProperty); }
            set { SetValue(PageSizesProperty, value); }
        }

        public static readonly DependencyProperty PageSizesProperty =
            DependencyProperty.Register(
                "PageSizes",
                typeof(List<int>),
                typeof(DataPager),
                new PropertyMetadata(new List<int>() { 1, 10, 20, 30, 40, 50 })
                );

        #endregion 依赖属性

        #region 初始化
        /// <summary>
        /// 初始化数据
        /// </summary>
        void InitData()
        {
            // 根据记录总数计算总页数
            if (TotalCount == 0)
                PageCount = 1;
            else
                PageCount = TotalCount % PageSize > 0 ? (TotalCount / PageSize) + 1 : TotalCount / PageSize;

            // 防止非法数据
            if (PageIndex < 1)
                PageIndex = 1;

            if (PageIndex > PageCount)
                PageIndex = PageCount;

            if (PageSize < 1)
                PageSize = 10;
        }
        #endregion

        #region 按钮逻辑
        /// <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(PageIndex - 1);
        }

        /// <summary>
        /// 点击下一页按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnNext_Click(object sender, RoutedEventArgs e)
        {
            OnPageChanging(PageIndex + 1);
        }

        /// <summary>
        /// 点击末页按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLast_Click(object sender, RoutedEventArgs e)
        {
            OnPageChanging(PageCount);
        }

        private void TxtPageIndex_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            Regex re = new Regex("[^0-9]+");
            e.Handled = re.IsMatch(e.Text);
        }

        /// <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);
            }
        }
        #endregion

        /// <summary>
        /// 页码更改
        /// </summary>
        /// <param name="pageIndex"></param>
        private void OnPageChanging(int pageIndex)
        {
            if (pageIndex < 1) pageIndex = 1;
            if (pageIndex > PageCount) pageIndex = PageCount;

            var eventArgs = new RoutedEventArgs(PageChangedEvent, this);
            PageIndex = pageIndex;
            RaiseEvent(eventArgs);
        }

        #region 控制按钮状态
        /// <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;
            }
        }

        /// <summary>
        /// 通知导航按钮(首页,上一页,下一页,末页)状态的更改
        /// </summary>
        void ChangeNavigationButtonState()
        {
            OnPropertyChanged("CanGoFirstOrPrev");
            OnPropertyChanged("CanGoLastOrNext");
        }

        #endregion

        #region INotifyPropertyChanged成员
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion INotifyPropertyChanged成员

        
    }
}

效果图:

相关推荐
Crazy Struggle19 小时前
.NET 8.0 通用管理平台,支持模块化、WinForms 和 WPF
vue·wpf·winform·.net 8.0·通用权限管理
呆萌很2 天前
HCIP-HarmonyOS Application Developer 习题(二十)
华为·wpf·harmonyos
九鼎科技-Leo2 天前
什么是 WPF 中的转换器?如何自定义一个值转换器?
开发语言·windows·c#·.net·wpf
为风而战2 天前
Deepin 系统中安装Rider和Uno Platform
linux·运维·.net·wpf
△曉風殘月〆2 天前
WPF MVVM入门系列教程(三、数据绑定)
c#·wpf·mvvm
^@^lemon tea^@^2 天前
.NET6中WPF项目添加System.Windows.Forms引用
wpf·.net6·windows.forms引用
九鼎科技-Leo2 天前
在 WPF 中,绑定机制是如何工作的?WPF数据绑定机制解析
windows·c#·.net·wpf
eggcode3 天前
使用ookii-dialogs-wpf在WPF选择文件夹时能输入路径
c#·wpf
code bean3 天前
【wpf】ResourceDictionary 字典资源的用法
windows·c#·wpf