最近在项目中遇到远程加载数据的问题,由于服务器采用分页方式返回数据,因此客户端也相应的制作了一个分页控件.代码相对简单,算做入门级的源码.

效果如图:

初步分析,分页功能只需要3个核心变量:PageIndex,PageSize,TotalCount,2个事件:PageChanging,PageChanged,1个方法InitData.

PageIndex:记录当前所在页

PageSize:记录每页显示的条目数

TotalCount:条目总数

由TotalCount和PageSize可以得到PageCount

PageChanging事件作为分页的预处理事件,修改事件参数PageChangingEventArgs的IsCancel属性可以取消分页,这个是参考其他分页控件的属性

PageChanged事件是分页后的处理事件,应用程序可以在此时获取PageIndex进行操作.

InitData方法在数据加载时调用(主要是TotalCount属性),用于初始化上面提到的核心变量.

WPF提供了很强大和实用的Binding功能,在开发控件时,应该尽量把属性设计成依赖属性.因此我把PageIndex,PageSize,TotalCount属性全部设计成依赖属性,并注册了部分回调方法.这样也可以很方便的实现控件和ViewModel的绑定.

核心代码如下:

 
///
    /// DataPager.xaml 的交互逻辑
    ///
    public partial class DataPager : UserControl, INotifyPropertyChanged
    {
        public DataPager()
        {
            InitializeComponent();
        }
        ///
        /// 分页前处理的事件,如果设置e.IsCancel=True将取消分页
        ///
        public event PageChangingRouteEventHandler PageChanging;
        ///
        /// 分页后处理的事件
        ///
        public event PageChangedRouteEventHandler PageChanged;
 
        #region 依赖属性
        ///
        /// 当前页
        ///
        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();
            }));
 
 
        ///
        /// 每页显示数据大小
        ///
        public int PageSize
        {
            get { return (int)GetValue(PageSizeProperty); }
            set { SetValue(PageSizeProperty, value); InitData(); }
        }
 
        // 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.ChangeNavigationButtonState();
            }));
 
 
        ///
        /// 记录数量
        ///
        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();
            }));
 
 
        ///
        /// 总页数
        ///
        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));
 
         
 
        ///
        /// 是否可以点击首页和上一页按钮
        ///
        public bool CanGoFirstOrPrev
        {
            get
            {
                if (PageIndex <= 1) return false;
                return true;
            }
        }
        ///
        /// 是否可以点击最后页和下一页按钮
        ///
        public bool CanGoLastOrNext
        {
            get
            {
                if (PageIndex >= PageCount) return false;
                return true;
            }
        }
        #endregion
        ///
        /// 点击首页按钮
        ///
        ///
        ///
        private void btnFirst_Click(object sender, RoutedEventArgs e)
        {
            OnPageChanging(1);
        }
        ///
        /// 点击上一页按钮
        ///
        ///
        ///
        private void btnPrev_Click(object sender, RoutedEventArgs e)
        {
            OnPageChanging(this.PageIndex - 1);
        }
        ///
        /// 点击下一页按钮
        ///
        ///
        ///
        private void btnNext_Click(object sender, RoutedEventArgs e)
        {
            OnPageChanging(this.PageIndex + 1);
        }
        ///
        /// 点击末页按钮
        ///
        ///
        ///
        private void btnLast_Click(object sender, RoutedEventArgs e)
        {
            OnPageChanging(this.PageCount);
        }
        ///
        /// 点击跳转按钮
        ///
        ///
        ///
        private void btnGoTo_Click(object sender, RoutedEventArgs e)
        {
            int pageIndex = 1;
            try
            {
                pageIndex = Convert.ToInt32(txtPageIndex.Text);
            }
            catch
            {
  
            }
            finally
            {
                OnPageChanging(pageIndex);
            }
        }
        ///
        /// 页码更改
        ///
        ///
        internal void OnPageChanging(int pageIndex)
        {
            if (pageIndex < 1) pageIndex = 1;
            if (pageIndex > this.PageCount) pageIndex = this.PageCount;
 
            var oldPageIndex = this.PageIndex;
            var newPageIndex = pageIndex;
            var eventArgs = new PageChangingEventArgs() { OldPageIndex = oldPageIndex, NewPageIndex = newPageIndex };
            if (this.PageChanging != null)
            {
                this.PageChanging(this, eventArgs);
            }
            if (!eventArgs.IsCancel)
            {
                this.PageIndex = newPageIndex;
                if (this.PageChanged != null)
                {
                    this.PageChanged.Invoke(this, new PageChangedEventArgs() { CurrentPageIndex = this.PageIndex });
                }
            }
        }
        ///
        /// 通知导航按钮(首页,上一页,下一页,末页)状态的更改
        ///
        void ChangeNavigationButtonState()
        {
            this.NotifyPropertyChanged("CanGoFirstOrPrev");
            this.NotifyPropertyChanged("CanGoLastOrNext");
        }
        ///
        /// 初始化数据
        ///
        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;
            }
        }
 
 
        #region INotifyPropertyChanged成员
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }

Xaml中使用如下:

<my:DataPager PageChanged="dataPager1_PageChanged" PageChanging="dataPager1_PageChanging"  TotalCount="{Binding TotalCount}" PageSize="20" PageIndex="{Binding PageIndex}" x:Name="dataPager1" VerticalAlignment="Top" />

下载位置:http://pan.baidu.com/s/1c26s3DY

WPF DataPager控件的更多相关文章

  1. WPF Popup 控件导致被遮挡内容不刷新的原因

    WPF Popup 控件导致被遮挡内容不刷新的原因 周银辉 今天在写一个WPF控件时用到了Popup控件,很郁闷的情况是:当popup关闭时,原来被popup挡住的界面部分不刷新,非要手动刷新一下(比 ...

  2. 创建 WPF 工具箱控件

    创建 WPF 工具箱控件 WPF (Windows Presentation Framework) 工具箱控件模板允许您创建 WPF 控件,会自动添加到 工具箱 安装扩展的安装. 本主题演示如何使用模 ...

  3. 《ASP.NET1200例》ListView 控件与DataPager控件的结合<二>

    ASP.NET使用ListView数据绑定控件和DataPager实现数据分页显示 为什么使用ListView+DataPager的方式实现分页显示? .net提供的诸多数据绑定控件,每一种都有它自己 ...

  4. 《ASP.NET1200例》ListView 控件与DataPager控件的结合<一>

    分页     在前一部分开始时介绍的原 HTML 设计中内含分页和排序,所以根据规范完整实现该网格的任务尚未完成.我们先分页,然后再排序. ListView 控件中的分页通过引入另一个新控件 Data ...

  5. Silverlight中DataPager控件扩展

    大家一定遇到这样的情况,想改变一下SL的DataPager的显示信息,比如希望分页控件上显示数据的总数.那么就需要扩展一下DataPager控件即可. 其实扩展DataPager很简单,只要获取到Da ...

  6. wpf打印控件 实现分页打印控件功能

    因为 要实现打印 wpf  listbox控件  数据特别多 要打印在 几张纸上    找了几天 都没有找到相关的例子 现在 解决了 在这里和大家分享一下 public void print(Fram ...

  7. WPF常用控件应用demo

    WPF常用控件应用demo 一.Demo 1.Demo截图如下: 2.demo实现过程 总体布局:因放大缩小窗体,控件很根据空间是否足够改变布局,故用WrapPanel布局. <ScrollVi ...

  8. WPF 分页控件 WPF 多线程 BackgroundWorker

    WPF 分页控件 WPF 多线程 BackgroundWorker 大家好,好久没有发表一篇像样的博客了,最近的开发实在头疼,很多东西无从下口,需求没完没了,更要命的是公司的开发从来不走正规流程啊, ...

  9. WPF Image控件中的ImageSource与Bitmap的互相转换

    原文:WPF Image控件中的ImageSource与Bitmap的互相转换  1.从bitmap转换成ImageSource [DllImport("gdi32.dll", ...

随机推荐

  1. c#获取新浪微博登录cookie

    用新浪微博api收集数据有诸多限制,每小时只能调用官方api函数150次,认证也很麻烦.因此想通过爬网页的方式来收集数据.访问新浪微博用户网页首先需要登录,登录获取cookie后可直接获取网页数据,无 ...

  2. 2016"百度之星" - 资格赛(Astar Round1) Problem C

    字典树. 插入的时候update一下节点出现的次数. delete的时候,先把前缀之后的全删了.然后看前缀最后一个节点出现了几次,然后前缀上每个节点的次数都减去这个次数. 前缀从上到下再检查一遍,如果 ...

  3. Word字体与像素的对应关系(转)

    源:Word字体与像素的对应关系 英文字体的1磅(pt),相当于1/72 英寸(inch),约等于1/2.8mm.12PT的字打印出来约为4.2mm.网页中12px的字才相当于12像素. 虽然 四号= ...

  4. (四)Jquery Mobile表单

    Jquery Mobile表单与列表 一.JM表单      1.表单      普通html表单            效果:          2.只能输入数字的表单           效果:  ...

  5. 路过Haxe

    刚才在看Nape的时候,看到Haxe的代码,意外的感觉到亲切. 因为之前写过as2代码,最近学习了python,所以对haxe看起来很亲切,于是路过一下写了个HelloWorld. 另外,估计很长时间 ...

  6. 滚动时div的背景图片随之滚动

    在浏览一些网站时发现有一种效果是当滚动时看到某一DIV的背景也会随之滚动,如下: 当滚动时内容位置保持不变,但是内容后面的背景却在随着滚动.随之我通过审查元素看到了其是通过background-pos ...

  7. 解决在某些IE浏览器下字符乱码的问题

    习惯上我们写字符声明都是 <meta charset="utf-8"> 在绝大多数浏览器都没有问题,但是在操蛋的IE上有时候会出现编码错误!! 解决方案: <me ...

  8. Spring自学教程-IOC、DI、AOP(二)

    一.spring的IOC-就是怎样使用spring来创建对象 二.springDI(依赖注入)-就是怎样给属性赋值 通过set方式赋值 以下我们只需要记住两点的赋值,基本类型和引用类型的赋值 基本类型 ...

  9. iOS子线程更新UI的两种方法

    http://blog.csdn.net/libaineu2004/article/details/45368427 方法1:performSelectorOnMainThread[self perf ...

  10. Mapreduce TopK

      思想比较简单,就是每个通过map来获取当前的数据块中的的topk个数据,然后将他们以相同的key值放到reduce中,最后通过reduce来对这n*k个数据排序并获得topk个数据.具体的就是建立 ...