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

初步分析,分頁功能只需要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的綁定.
核心代碼如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
///
/// 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" />
注意:在使用MVVM框架的情況下,如果在vm里獲取分頁相關的數據,需要使用雙向綁定,比如:PageIndex="{Binding PageIndex,Mode=TwoWay}"
出處:https://www.cnblogs.com/scheshan/archive/2012/06/19/2554550.html
=======================================================================
推薦WPF相關文章:
