1 // System.Web.UI.WebControls.PagedDataSource.cs
3 // Author: Duncan Mak (duncan@novell.com)
4 // Jackson Harper (jackson@ximian.com)
6 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 using System
.Collections
;
29 using System
.ComponentModel
;
30 using System
.Security
.Permissions
;
32 namespace System
.Web
.UI
.WebControls
{
34 // CAS - no inheritance demand required because the class is sealed
35 [AspNetHostingPermission (SecurityAction
.LinkDemand
, Level
= AspNetHostingPermissionLevel
.Minimal
)]
36 public sealed class PagedDataSource
: ICollection
, IEnumerable
, ITypedList
38 int page_size
, current_page_index
, virtual_count
;
39 bool allow_paging
, allow_custom_paging
;
43 bool allow_server_paging
;
46 public PagedDataSource ()
51 public bool AllowCustomPaging
{
52 get { return allow_custom_paging; }
54 allow_custom_paging
= value;
56 // AllowCustomPaging and AllowServerPaging are mutually exclusive
57 if (allow_custom_paging
)
58 allow_server_paging
= false;
63 public bool AllowPaging
{
64 get { return allow_paging; }
65 set { allow_paging = value; }
73 if (IsPagingEnabled
) {
74 if (IsCustomPagingEnabled
|| !IsLastPage
)
76 return DataSourceCount
- FirstIndexInPage
;
79 return DataSourceCount
;
83 public int CurrentPageIndex
{
84 get { return current_page_index; }
85 set { current_page_index = value; }
88 public IEnumerable DataSource
{
89 get { return source; }
90 set { source = value; }
93 public int DataSourceCount
{
98 if (IsCustomPagingEnabled
100 || IsServerPagingEnabled
103 return virtual_count
;
105 if (source
is ICollection
)
106 return ((ICollection
) source
).Count
;
108 throw new HttpException ("The data source must implement ICollection");
112 public int FirstIndexInPage
{
114 if (!IsPagingEnabled
|| IsCustomPagingEnabled
||
116 IsServerPagingEnabled
||
121 return current_page_index
* page_size
;
125 public bool IsCustomPagingEnabled
{
126 get { return IsPagingEnabled && allow_custom_paging; }
130 public bool IsServerPagingEnabled
{
131 get { return IsPagingEnabled && allow_server_paging; }
135 public bool IsFirstPage
{
140 return current_page_index
== 0;
144 public bool IsLastPage
{
146 if (!allow_paging
|| page_size
== 0)
149 return (current_page_index
== (PageCount
- 1));
153 public bool IsPagingEnabled
{
154 get { return (allow_paging && page_size != 0); }
157 public bool IsReadOnly
{
158 get { return false; }
// as documented
161 public bool IsSynchronized
{
162 get { return false; }
// as documented
165 public int PageCount
{
170 if (!IsPagingEnabled
|| DataSourceCount
== 0 || page_size
== 0)
173 return (DataSourceCount
+ page_size
- 1) / page_size
;
177 public int PageSize
{
178 get { return page_size; }
179 set { page_size = value; }
182 public object SyncRoot
{
186 public int VirtualCount
{
187 get { return virtual_count; }
188 set { virtual_count = value; }
191 public bool AllowServerPaging
{
193 return allow_server_paging
;
196 allow_server_paging
= value;
197 // AllowCustomPaging and AllowServerPaging are mutually exclusive
198 if (allow_server_paging
)
199 allow_custom_paging
= false;
204 public void CopyTo (Array array
, int index
)
206 foreach (object o
in source
)
207 array
.SetValue (o
, index
++);
210 public IEnumerator
GetEnumerator ()
212 // IList goes first, as it implements ICollection
213 IList list
= source
as IList
;
218 first
= FirstIndexInPage
;
219 count
= ((ICollection
) source
).Count
;
220 limit
= ((first
+ page_size
) > count
) ? (count
- first
) : page_size
;
221 return GetListEnum (list
, first
, first
+ limit
);
224 ICollection col
= source
as ICollection
;
226 first
= FirstIndexInPage
;
228 limit
= ((first
+ page_size
) > count
) ? (count
- first
) : page_size
;
229 return GetEnumeratorEnum (col
.GetEnumerator (), first
, first
+ page_size
);
232 return source
.GetEnumerator ();
235 public PropertyDescriptorCollection
GetItemProperties (PropertyDescriptor
[] list_accessors
)
237 ITypedList typed
= source
as ITypedList
;
240 return typed
.GetItemProperties (list_accessors
);
243 public string GetListName (PropertyDescriptor
[] list_accessors
)
245 return String
.Empty
; // as documented
248 private IEnumerator
GetListEnum (IList list
, int start
, int end
)
252 else if (start
>= list
.Count
)
255 for (int i
= start
; i
< end
; i
++)
256 yield return list
[i
];
259 private IEnumerator
GetEnumeratorEnum (IEnumerator e
, int start
, int end
)
261 for (int i
= 0; i
< start
; i
++)
263 for (int i
= start
; (!allow_paging
|| i
< end
) && e
.MoveNext (); i
++)
264 yield return e
.Current
;