WPF 實現 DataGrid/ListView 分頁控件

原文:WPF 實現 DataGrid/ListView 分頁控件

在WPF中,通常會選用DataGrid/ListView進行數據展示,如果數據量不多,可以直接一個頁面顯示出來。如果數據量很大,2000條數據,一次性顯示在一個頁面中,不僅消耗資源,而且用戶體驗也很糟糕。這篇博客將介紹如何創建一個分頁控件。

為了簡單起見,這個分頁控件目前只有 首頁/上一頁/下一頁/末頁/總頁數/第幾頁 等功能。實現思路,首頁/上一頁/下一頁/末頁 這四個通過路由事件來實現,在使用時可以使用命令進行綁定,或者直接使用均可。總頁數和第幾頁通過依賴屬性來實現,使用時將頁數進行綁定顯示即可。示例代碼如下:

Pager控件:

    <UserControl.Resources><Style TargetType="{x:Type Button}"><Setter Property="Width" Value="22"/><Setter Property="Height" Value="22"/></Style></UserControl.Resources><Grid><StackPanel Orientation="Horizontal"><Button x:Name="FirstPageButton" Margin="5,0" Click="FirstPageButton_Click"><Path Width="7" Height="10" Data="M0,0L0,10 M0,5L6,2 6,8 0,5" Stroke="Black" StrokeThickness="1" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center" /></Button><Button x:Name="PreviousPageButton" Margin="0,0,5,0" Click="PreviousPageButton_Click"><Path Width="8" Height="8" Data="M0,4L8,0 8,8z" Stroke="Black" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center" /></Button><TextBlock VerticalAlignment="Center"><Run Text="第"/><Run x:Name="rCurrent" Text="0"/><Run Text="頁"/></TextBlock><Button Margin="5,0" x:Name="NextPageButton" Click="NextPageButton_Click"><Path Width="8" Height="8" Data="M0,4L8,0 8,8z" Stroke="Black" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center"><Path.RenderTransform><RotateTransform Angle="180" CenterX="4" CenterY="4" /></Path.RenderTransform></Path></Button><Button Margin="0,0,5,0" x:Name="LastPageButton" Click="LastPageButton_Click"><Path x:Name="MainPath" Width="7" Height="10" Data="M0,0L0,10 M0,5 L6,2 6,8 0,5" Stroke="Black" StrokeThickness="1" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center"><Path.RenderTransform><RotateTransform Angle="180" CenterX="3" CenterY="5" /></Path.RenderTransform></Path></Button><TextBlock VerticalAlignment="Center"><Run Text="共"/><Run x:Name="rTotal" Text="0"/><Run Text="頁"/></TextBlock></StackPanel>     </Grid>

C#:

    public partial class Pager : UserControl{public static RoutedEvent FirstPageEvent;public static RoutedEvent PreviousPageEvent;public static RoutedEvent NextPageEvent;public static RoutedEvent LastPageEvent;public static readonly DependencyProperty CurrentPageProperty;public static readonly DependencyProperty TotalPageProperty;public string CurrentPage{get { return (string)GetValue(CurrentPageProperty); }set { SetValue(CurrentPageProperty, value); }}public string TotalPage{get { return (string)GetValue(TotalPageProperty); }set { SetValue(TotalPageProperty, value); }}public Pager(){InitializeComponent();}static Pager(){FirstPageEvent = EventManager.RegisterRoutedEvent("FirstPage", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(Pager));PreviousPageEvent = EventManager.RegisterRoutedEvent("PreviousPage", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(Pager));NextPageEvent = EventManager.RegisterRoutedEvent("NextPage", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(Pager));LastPageEvent = EventManager.RegisterRoutedEvent("LastPage", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(Pager));CurrentPageProperty = DependencyProperty.Register("CurrentPage", typeof(string), typeof(Pager), new PropertyMetadata(string.Empty,new PropertyChangedCallback(OnCurrentPageChanged)));TotalPageProperty = DependencyProperty.Register("TotalPage", typeof(string), typeof(Pager), new PropertyMetadata(string.Empty,new PropertyChangedCallback(OnTotalPageChanged)));}public event RoutedEventHandler FirstPage{add { AddHandler(FirstPageEvent, value); }remove { RemoveHandler(FirstPageEvent, value); }}public event RoutedEventHandler PreviousPage{add { AddHandler(PreviousPageEvent, value); }remove { RemoveHandler(PreviousPageEvent, value); }}public event RoutedEventHandler NextPage{add { AddHandler(NextPageEvent, value); }remove { RemoveHandler(NextPageEvent, value); }}public event RoutedEventHandler LastPage{add { AddHandler(LastPageEvent, value); }remove { RemoveHandler(LastPageEvent, value); }}public static void OnTotalPageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){Pager p = d as Pager;if(p != null){Run rTotal = (Run)p.FindName("rTotal");rTotal.Text = (string)e.NewValue;}}private static void OnCurrentPageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){Pager p = d as Pager;if(p != null){Run rCurrrent = (Run)p.FindName("rCurrent");rCurrrent.Text = (string)e.NewValue;}}private void FirstPageButton_Click(object sender, RoutedEventArgs e){RaiseEvent(new RoutedEventArgs(FirstPageEvent, this));}private void PreviousPageButton_Click(object sender, RoutedEventArgs e){RaiseEvent(new RoutedEventArgs(PreviousPageEvent, this));}private void NextPageButton_Click(object sender, RoutedEventArgs e){RaiseEvent(new RoutedEventArgs(NextPageEvent, this));}private void LastPageButton_Click(object sender, RoutedEventArgs e){RaiseEvent(new RoutedEventArgs(LastPageEvent, this));}}
View Code

在MainWindow中,
XAML:

    <Grid><Grid.RowDefinitions><RowDefinition Height="*"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><DataGrid Grid.Row="0" ItemsSource="{Binding FakeSource}" AutoGenerateColumns="False" CanUserAddRows="False"><DataGrid.Columns><DataGridTextColumn Header="Item Id" Binding="{Binding Id}" Width="80"/><DataGridTextColumn Header="Item Name" Binding="{Binding ItemName}" Width="180"/></DataGrid.Columns></DataGrid><local:Pager TotalPage="{Binding TotalPage}"CurrentPage="{Binding CurrentPage, Mode=TwoWay}" HorizontalAlignment="Center"Grid.Row="1"><i:Interaction.Triggers><i:EventTrigger EventName="FirstPage"><i:InvokeCommandAction Command="{Binding FirstPageCommand}" /></i:EventTrigger><i:EventTrigger EventName="PreviousPage"><i:InvokeCommandAction Command="{Binding PreviousPageCommand}"/></i:EventTrigger><i:EventTrigger EventName="NextPage"><i:InvokeCommandAction Command="{Binding NextPageCommand}" /></i:EventTrigger><i:EventTrigger EventName="LastPage"><i:InvokeCommandAction Command="{Binding LastPageCommand}"/></i:EventTrigger></i:Interaction.Triggers></local:Pager></Grid>

MainViewModel類:

public class MainViewModel : ViewModel{private ICommand _firstPageCommand;public ICommand FirstPageCommand{get{return _firstPageCommand;}set{_firstPageCommand = value;}}private ICommand _previousPageCommand;public ICommand PreviousPageCommand{get{return _previousPageCommand;}set{_previousPageCommand = value;}}private ICommand _nextPageCommand;public ICommand NextPageCommand{get{return _nextPageCommand;}set{_nextPageCommand = value;}}private ICommand _lastPageCommand;public ICommand LastPageCommand{get{return _lastPageCommand;}set{_lastPageCommand = value;}}private int _pageSize;public int PageSize{get{return _pageSize;}set{if(_pageSize != value){_pageSize = value;OnPropertyChanged("PageSize");}}}private int _currentPage;public int CurrentPage{get{return _currentPage;}set{if(_currentPage != value){_currentPage = value;OnPropertyChanged("CurrentPage");}}}private int _totalPage;public int TotalPage{get{return _totalPage;}set{if(_totalPage != value){_totalPage = value;OnPropertyChanged("TotalPage");}}}private ObservableCollection<FakeDatabase> _fakeSoruce;public ObservableCollection<FakeDatabase> FakeSource{get{return _fakeSoruce;}set{if(_fakeSoruce != value){_fakeSoruce = value;OnPropertyChanged("FakeSource");}}}private List<FakeDatabase> _source;public MainViewModel(){_currentPage = 1;_pageSize = 20;FakeDatabase fake = new FakeDatabase();_source = fake.GenerateFakeSource();_totalPage = _source.Count / _pageSize;_fakeSoruce = new ObservableCollection<FakeDatabase>();List<FakeDatabase> result = _source.Take(20).ToList();_fakeSoruce.Clear();_fakeSoruce.AddRange(result);_firstPageCommand = new DelegateCommand(FirstPageAction);_previousPageCommand = new DelegateCommand(PreviousPageAction);_nextPageCommand = new DelegateCommand(NextPageAction);_lastPageCommand = new DelegateCommand(LastPageAction);}private void FirstPageAction(){CurrentPage = 1;var result = _source.Take(_pageSize).ToList();_fakeSoruce.Clear();_fakeSoruce.AddRange(result);}private void PreviousPageAction(){if(CurrentPage == 1){return;}List<FakeDatabase> result = new List<FakeDatabase>();if(CurrentPage == 2){result = _source.Take(_pageSize).ToList();}else{result = _source.Skip((CurrentPage - 2) * _pageSize).Take(_pageSize).ToList();}_fakeSoruce.Clear();_fakeSoruce.AddRange(result);CurrentPage--;}private void NextPageAction(){if(CurrentPage == _totalPage){return;}List<FakeDatabase> result = new List<FakeDatabase>();result = _source.Skip(CurrentPage * _pageSize).Take(_pageSize).ToList();_fakeSoruce.Clear();_fakeSoruce.AddRange(result);CurrentPage++;}private void LastPageAction(){CurrentPage = TotalPage;int skipCount = (_totalPage - 1) * _pageSize;int takeCount = _source.Count - skipCount;var result = _source.Skip(skipCount).Take(takeCount).ToList();_fakeSoruce.Clear();_fakeSoruce.AddRange(result);}}
View Code

綁定到UI的數據源只是需要顯示的數據,不會把所有數據都取出來。當選擇顯示頁數時,只需要將新的數據源附上即可。

總結:如果需要對該分頁控件進行擴展,例如,增加每頁顯示條數功能,只需要在Pager控件中增加相應的依賴屬性即可。

感謝您的閱讀,代碼點擊這里下載。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276920.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276920.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276920.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Sql Server 中漢字處理排序規則,全角半角

--1. 為數據庫指定排序規則CREATEDATABASEdb COLLATE Chinese_PRC_CI_ASGOALTERDATABASEdb COLLATE Chinese_PRC_BINGO/**//**/--2. 為表中的列指定排序規則CREATETABLEtb(col1 varchar(10),col2 varchar(10) COLLATE Chinese_PRC_CI_AS)GOALTERTABLEtb ADDcol3 varchar(10) CO…

解決局域網設置固定IP后無法上網?

1.cmd中輸入ipconfig /all查看ip和dns的狀態 2.查看自動獲取的dns是什么,然后手動設置ip和dns時,和自動獲取的保持一樣即可 注解&#xff1a;設置后還是無法上網后主要檢查ip與dns是否設置錯誤. 轉載于:https://www.cnblogs.com/yanans/p/11301061.html

鼠標輸入

一、隱藏并捕捉光標 偏航角和俯仰角是通過鼠標移動獲得的&#xff0c;水平的移動影響偏航角&#xff0c;豎直的移動影響俯仰角。 原理是&#xff0c;存儲上一幀鼠標的位置&#xff0c;在當前幀中計算鼠標位置與上一幀的位置相差多少。如果水平/豎直差別越大&#xff0c;那么俯仰…

c#用canny算子做邊緣提取_機器視覺學習(三)邊緣檢測

一、邊緣檢測二、邊緣檢測流程三、Canny邊緣檢測前言邊緣檢測是圖像處理和計算機視覺中&#xff0c;尤其是特征提取中的一個研究領域。有許多方法用于邊緣檢測&#xff0c;它們的絕大部分可以劃分為兩類&#xff1a;基于一階導數首先計算邊緣強度&#xff0c; 通常用一階導數表…

一個有關Update類型的存儲過程的問題

CREATE PROCEDURE testupdateproc AS declare id int declare trandate datetime declare tranlimit int update test set trandatetrandate, tranlimittranlimit where test.idid GO 存儲過程語句如上&#xff0c;檢查語法是沒有問題的&#xff0c;但是在程序中執行時卻不行…

[20190805]在小程序中使用npm包

小程序是可以使用npm包的 1. 初始化npm&#xff1b;&#xff08;在項目目錄下輸入&#xff09; npm init 此時項目文件夾會創建一個配置信息的package.json文件 2. 手動新建node_modules文件夾&#xff1b;&#xff08;在項目目錄下新建&#xff09; 3. 安裝npm包&#xff1b; …

bindresult必須在哪個位置_手機視頻剪輯工具哪個好?清爽視頻編輯APP有人推薦嗎?...

作為一個非常喜歡旅游的人&#xff0c;每次出門在外都喜歡發各種照片&#xff0c;以前發照片覺得就能夠表達自己的狀態和心情&#xff0c;但是隨著時間的變化發現&#xff0c;身邊的人都開始喜歡發視頻了。此前在飛機上拍攝了一段覺得不錯的天空視頻&#xff0c;想要制作成短片…

[轉] 能ping通,但不能上網.

一、感染了病毒所致這種情況往往表現在打開IE時&#xff0c;在IE界面的左下框里提示&#xff1a;正在打開網頁&#xff0c;但老半天沒響應。在任務管理器里查看進程&#xff0c;&#xff08;進入方法&#xff0c;把鼠標放在任務欄上&#xff0c;按右鍵—任務管理器—進程&#…

Gradle打包命令記錄

Gradle打包命令記錄第一種方式&#xff1a;gradle build執行后在在build/lib下生成war包第二種方式&#xff1a;gradle cleangradle --refresh-dependencies assemble

淺談ASP中Web頁面間的數據傳遞

【簡 介】  基于Web的動態網頁設計必會涉及到頁面間的數據傳遞&#xff0c;文章探討了ASP設計中常用的Web頁面間的數據傳遞方式&#xff0c;分析各種數據傳遞方式的使用方法、使用場合及優缺點&#xff0c;其都是設計階段選擇數據傳遞方式考慮的關鍵 往往使用動態網頁技術制作…

變頻電源出現故障了怎么辦,該如何去診斷呢

在變頻電源使用時間過長之后就會出現一些小故障&#xff0c;在出現這些小故障的時候很多人都不知道問題出在哪&#xff0c;今天中港揚盛的技術員教你如何的快速診斷變頻電源的故障方法。只有及時的發現&#xff0c;這樣就能夠有效地去解決變頻電源所出現的故障。下面就是變頻電…

無法訪問你試圖使用的功能所在的網絡位置_[steam實用工具]解決無法訪問商店/社區/好友列表的問題...

[steam實用工具]解決無法訪問商店/社區/好友列表的問題在我們使用steam的過程中&#xff0c;由于某些原因&#xff0c;在訪問商店/社區/好友列表時會被受到限制。針對這種情況&#xff0c;國內的大神些開發出了以下工具來解決我們訪問的難題。本文章中的軟件由“羽翼誠"大…

tomcat6.0+mysql5.0+jdk5.0+myeclipse6.0打造JSP開發平臺

1.下載tomcat6.0(http://tomcat.apache.org/download-60.cgi), mysql5.0(http://download.mysql.cn/src/2006/0710/5543.html), jdk5.0(http://download.mysql.cn/src/2006/0710/5543.html)以及myeclipse6.0(http://www.myeclipseide.com/module-htmlpages-display-pid-4.html)…

程序設計中的感悟

1. 學習應該從基礎打起&#xff0c;不要一開始就嘗試最高深的技術。 2. 每看一本書&#xff0c;不要說這章我以前學習過了&#xff0c;也掌握的很好&#xff0c;因此我可以跳過這一章看更重要的了。 3. 對于作業&#xff0c;遇到不會的盡量不要立刻向別人請教。如果實在解決…

(轉)用Java獲得當前性能信息

(轉&#xff09;用Java獲得當前性能信息 http://www.blogjava.net/amigoxie/archive/2008/04/30/197564.html在Java中&#xff0c;可以獲得總的物理內存、剩余的物理內存、已使用的物理內存等信息&#xff0c;本例講解如何取得這些信息&#xff0c;并且獲得在Windows下的內存使…

docker wsl2啟動不了_Docker學習筆記

在筆記本上主要還是想以輕量、方便為主&#xff0c;所以采用的是在WSL2中使用docker的這么一個方案。WSL2我筆記本原來是預裝的是WIN10家庭版&#xff0c;需要先升級為專業版&#xff0c;并加入windows預覽體驗計劃。更新完之后&#xff0c;安裝WSL&#xff0c;我選擇的是Ubunt…

暑假集訓-8.06總結

學習內容&#xff1a; 搜索 今日完成題數&#xff08;不包含多校&#xff09;&#xff1a;4 今日看書情況&#xff1a;15頁 今日心得&#xff1a; 今天學的是搜索&#xff0c;雖然以前學過&#xff0c;但書上講的更具體些&#xff0c; 比如說如何去優化搜索的次數等 英語題目好…

網易馬進:DDB從分布式數據庫到結構化數據中心的架構變遷

導語&#xff1a; 本文根據馬進老師在2018年5月10日【第九屆中國數據庫技術大會(DTCC)】現場演講內容整理而成。馬進 網易 DDB項目負責人來自網易杭研大數據平臺組&#xff0c;入職以來先后參與了分布式數據庫DDB&#xff0c;緩存NKV&#xff0c;網易數據運河NDC等項目&#xf…

element label動態賦值_淺析 vuerouter 源碼和動態路由權限分配

背景上月立過一個 flag&#xff0c;看完 vue-router 的源碼&#xff0c;可到后面逐漸發現 vue-router 的源碼并不是像很多總結的文章那么容易理解&#xff0c;閱讀過你就會發現里面的很多地方都會有多層的函數調用關系&#xff0c;還有大量的 this 指向問題&#xff0c;而且會有…

MessagePack Java 0.6.X List, Map 對象的序列化和反序列化

為了序列化原生的容器對象例如 List 和 Map 對象&#xff0c;你必須使用 Template。 Template 對象是 serializer 和 deserializer 的配對。例如&#xff0c;為了序列化一個 List 對象&#xff0c;在 List 對象中 Integer 對象為元素&#xff0c;你可以使用下面的方法來創建一…