WPF DataPager控件


最近在項目中遇到遠程加載數據的問題,由於服務器采用分頁方式返回數據,因此客戶端也相應的制作了一個分頁控件.代碼相對簡單,算做入門級的源碼.

 

效果如圖:

初步分析,分頁功能只需要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" />

 

源碼下載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM