1 // 2 // System.Web.UI.WebControls.NumericPagerField 3 // 4 // Authors: 5 // Marek Habersack (mhabersack@novell.com) 6 // 7 // (C) 2007-2010 Novell, Inc 8 // 9 10 // 11 // Permission is hereby granted, free of charge, to any person obtaining 12 // a copy of this software and associated documentation files (the 13 // "Software"), to deal in the Software without restriction, including 14 // without limitation the rights to use, copy, modify, merge, publish, 15 // distribute, sublicense, and/or sell copies of the Software, and to 16 // permit persons to whom the Software is furnished to do so, subject to 17 // the following conditions: 18 // 19 // The above copyright notice and this permission notice shall be 20 // included in all copies or substantial portions of the Software. 21 // 22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 // 30 using System; 31 using System.Globalization; 32 using System.Security.Permissions; 33 using System.Web; 34 using System.Web.UI; 35 36 namespace System.Web.UI.WebControls 37 { 38 [AspNetHostingPermissionAttribute(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] 39 [AspNetHostingPermissionAttribute(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] 40 public class NumericPagerField : DataPagerField 41 { 42 const string Default_NextPageText = "..."; 43 const string Default_PreviousPageText = "..."; 44 45 int _startRowIndex; 46 int _maximumRows; 47 int _totalRowCount; 48 int _fieldIndex; 49 bool _renderNonBreakingSpacesBetweenControls = true; 50 NumericPagerField()51 public NumericPagerField () 52 { 53 } 54 CopyProperties(DataPagerField newField)55 protected override void CopyProperties (DataPagerField newField) 56 { 57 base.CopyProperties (newField); 58 59 NumericPagerField field = newField as NumericPagerField; 60 if (field == null) 61 return; 62 63 field.ButtonCount = ButtonCount; 64 field.ButtonType = ButtonType; 65 field.CurrentPageLabelCssClass = CurrentPageLabelCssClass; 66 field.NextPageImageUrl = NextPageImageUrl; 67 field.NextPageText = NextPageText; 68 field.NextPreviousButtonCssClass = NextPreviousButtonCssClass; 69 field.NumericButtonCssClass = NumericButtonCssClass; 70 field.PreviousPageImageUrl = PreviousPageImageUrl; 71 field.PreviousPageText = PreviousPageText; 72 field.RenderNonBreakingSpacesBetweenControls = RenderNonBreakingSpacesBetweenControls; 73 } 74 CreateDataPagers(DataPagerFieldItem container, int startRowIndex, int maximumRows, int totalRowCount, int fieldIndex)75 public override void CreateDataPagers (DataPagerFieldItem container, int startRowIndex, int maximumRows, int totalRowCount, int fieldIndex) 76 { 77 _startRowIndex = startRowIndex; 78 _maximumRows = maximumRows; 79 _totalRowCount = totalRowCount; 80 _fieldIndex = fieldIndex; 81 82 bool setPagePropertiesNeeded = false; 83 bool queryMode = GetQueryModeStartRowIndex (_totalRowCount, _maximumRows, ref _startRowIndex, ref setPagePropertiesNeeded); 84 bool addNonBreakingSpace = RenderNonBreakingSpacesBetweenControls; 85 int buttonCount = ButtonCount; 86 int totalPages = totalRowCount / maximumRows + (totalRowCount % maximumRows > 0 ? 1 : 0); 87 int currentPage = startRowIndex == 0 ? 1 : (startRowIndex / maximumRows) + 1; 88 int activePage = ((startRowIndex / (maximumRows * buttonCount)) * buttonCount) + 1; 89 int lastPage = activePage + buttonCount - 1; 90 91 bool showPreviousPage = activePage > buttonCount; 92 bool showNextPage = totalPages - activePage >= buttonCount; 93 94 if (lastPage > totalPages) 95 lastPage = totalPages; 96 97 int newPageNum; 98 if (showPreviousPage) { 99 newPageNum = activePage - 1; 100 if (newPageNum < 1) 101 newPageNum = 1; 102 103 CreateButton (container, DataControlCommands.PreviousPageCommandArgument, PreviousPageText, PreviousPageImageUrl, 104 NextPreviousButtonCssClass, newPageNum, queryMode, true, addNonBreakingSpace, false); 105 } 106 107 string numericButtonCssClass = NumericButtonCssClass; 108 bool enabled; 109 string pageString; 110 while (activePage <= lastPage) { 111 enabled = activePage != currentPage; 112 pageString = activePage.ToString (CultureInfo.InvariantCulture); 113 CreateButton (container, pageString, pageString, String.Empty, 114 enabled ? numericButtonCssClass : CurrentPageLabelCssClass, activePage, 115 queryMode, enabled, addNonBreakingSpace, true); 116 activePage++; 117 } 118 if (showNextPage && addNonBreakingSpace) 119 container.Controls.Add (new LiteralControl (" ")); 120 121 if (showNextPage) 122 CreateButton (container, DataControlCommands.NextPageCommandArgument, NextPageText, NextPageImageUrl, 123 NextPreviousButtonCssClass, activePage, queryMode, true, addNonBreakingSpace, false); 124 125 if (setPagePropertiesNeeded) 126 DataPager.SetPageProperties (_startRowIndex, _maximumRows, true); 127 } 128 CreateButton(DataPagerFieldItem container, string commandName, string text, string imageUrl, string cssClass, int pageNum, bool queryMode, bool enabled, bool addNonBreakingSpace, bool isPageNumber)129 void CreateButton (DataPagerFieldItem container, string commandName, string text, string imageUrl, string cssClass, int pageNum, 130 bool queryMode, bool enabled, bool addNonBreakingSpace, bool isPageNumber) 131 { 132 WebControl ctl = null; 133 134 if (queryMode) { 135 if (isPageNumber && !enabled) { 136 var span = new Label (); 137 span.Text = text; 138 span.CssClass = cssClass; 139 ctl = span; 140 } else { 141 HyperLink h = new HyperLink (); 142 h.Text = text; 143 h.ImageUrl = imageUrl; 144 h.Enabled = enabled; 145 h.NavigateUrl = GetQueryStringNavigateUrl (pageNum); 146 h.CssClass = cssClass; 147 ctl = h; 148 } 149 } else { 150 if (!enabled) { 151 Label l = new Label (); 152 l.Text = text; 153 l.CssClass = cssClass; 154 ctl = l; 155 } else { 156 switch (ButtonType) { 157 case ButtonType.Button: 158 Button btn = new Button (); 159 btn.CommandName = commandName; 160 btn.CommandArgument = pageNum.ToString (); 161 btn.Text = text; 162 break; 163 164 case ButtonType.Link: 165 LinkButton lbtn = new LinkButton (); 166 lbtn.CommandName = commandName; 167 lbtn.CommandArgument = pageNum.ToString (); 168 lbtn.Text = text; 169 ctl = lbtn; 170 break; 171 172 case ButtonType.Image: 173 ImageButton ibtn = new ImageButton (); 174 ibtn.CommandName = commandName; 175 ibtn.CommandArgument = pageNum.ToString (); 176 ibtn.ImageUrl = imageUrl; 177 ibtn.AlternateText = text; 178 ctl = ibtn; 179 break; 180 } 181 182 if (ctl != null) 183 ctl.CssClass = cssClass; 184 } 185 } 186 187 if (ctl != null) { 188 container.Controls.Add (ctl); 189 if (addNonBreakingSpace) 190 container.Controls.Add (new LiteralControl (" ")); 191 } 192 } CreateField()193 protected override DataPagerField CreateField () 194 { 195 return new NumericPagerField (); 196 } 197 Equals(object o)198 public override bool Equals (object o) 199 { 200 NumericPagerField field = o as NumericPagerField; 201 202 if (field == null) 203 return false; 204 205 if (field.ButtonCount != ButtonCount) 206 return false; 207 208 if (field.ButtonType != ButtonType) 209 return false; 210 211 if (String.Compare (field.CurrentPageLabelCssClass, CurrentPageLabelCssClass, StringComparison.Ordinal) != 0) 212 return false; 213 214 if (String.Compare (field.NextPageImageUrl, NextPageImageUrl, StringComparison.Ordinal) != 0) 215 return false; 216 217 if (String.Compare (field.NextPageText, NextPageText, StringComparison.Ordinal) != 0) 218 return false; 219 220 if (String.Compare (field.NextPreviousButtonCssClass, NextPreviousButtonCssClass, StringComparison.Ordinal) != 0) 221 return false; 222 223 if (String.Compare (field.NumericButtonCssClass, NumericButtonCssClass, StringComparison.Ordinal) != 0) 224 return false; 225 226 if (String.Compare (field.PreviousPageImageUrl, PreviousPageImageUrl, StringComparison.Ordinal) != 0) 227 return false; 228 229 if (String.Compare (field.PreviousPageText, PreviousPageText, StringComparison.Ordinal) != 0) 230 return false; 231 232 if (field.RenderNonBreakingSpacesBetweenControls != RenderNonBreakingSpacesBetweenControls) 233 return false; 234 235 return true; 236 } 237 GetHashCode()238 public override int GetHashCode () 239 { 240 int ret = 0; 241 242 // Base the calculation on the properties that are copied in CopyProperties 243 ret |= ButtonCount.GetHashCode (); 244 ret |= ButtonType.GetHashCode (); 245 ret |= CurrentPageLabelCssClass.GetHashCode (); 246 ret |= NextPageImageUrl.GetHashCode (); 247 ret |= NextPageText.GetHashCode (); 248 ret |= NextPreviousButtonCssClass.GetHashCode (); 249 ret |= NumericButtonCssClass.GetHashCode (); 250 ret |= PreviousPageImageUrl.GetHashCode (); 251 ret |= PreviousPageText.GetHashCode (); 252 ret |= RenderNonBreakingSpacesBetweenControls.GetHashCode (); 253 254 return ret; 255 } 256 HandleEvent(CommandEventArgs e)257 public override void HandleEvent (CommandEventArgs e) 258 { 259 string commandName = e.CommandName; 260 int pageNum; 261 262 if (!Int32.TryParse (e.CommandArgument as string, out pageNum)) 263 pageNum = 0; 264 else if (pageNum >= 1) 265 pageNum--; 266 else if (pageNum < 0) 267 pageNum = 0; 268 269 int newStartIndex = -1; 270 int pageSize = DataPager.PageSize; 271 int offset = pageSize * pageNum; 272 273 if (String.Compare (commandName, DataControlCommands.NextPageCommandArgument, StringComparison.OrdinalIgnoreCase) == 0 || 274 String.Compare (commandName, DataControlCommands.PreviousPageCommandArgument, StringComparison.OrdinalIgnoreCase) == 0) { 275 newStartIndex = offset; 276 } else 277 newStartIndex = (Int32.Parse (commandName) - 1) * pageSize; 278 279 if (newStartIndex != -1) 280 DataPager.SetPageProperties (newStartIndex, pageSize, true); 281 } 282 283 public int ButtonCount { 284 get { 285 object o = ViewState ["ButtonCount"]; 286 if (o != null) 287 return (int)o; 288 289 return 5; 290 } 291 292 set { 293 if (value < 1) 294 throw new ArgumentOutOfRangeException ("value", "The ButtonCount property is set to a value less than 1."); 295 296 ViewState ["ButtonCount"] = value; 297 } 298 } 299 300 public ButtonType ButtonType { 301 get { 302 object o = ViewState ["ButtonType"]; 303 if (o != null) 304 return (ButtonType)o; 305 306 return ButtonType.Link; 307 } 308 309 set { 310 if (!Enum.IsDefined (typeof (ButtonType), value)) 311 throw new ArgumentOutOfRangeException ("value", "The value for the ButtonType property is not one of the ButtonType values."); 312 313 ViewState ["ButtonType"] = value; 314 } 315 } 316 317 public string CurrentPageLabelCssClass { 318 get { 319 string s = ViewState ["CurrentPageLabelCssClass"] as string; 320 if (s != null) 321 return s; 322 323 return String.Empty; 324 } 325 326 set { 327 if (String.IsNullOrEmpty (value)) 328 return; 329 330 ViewState ["CurrentPageLabelCssClass"] = value; 331 } 332 } 333 334 public string NextPageImageUrl { 335 get { 336 string s = ViewState ["NextPageImageUrl"] as string; 337 if (s != null) 338 return s; 339 340 return String.Empty; 341 } 342 343 set { 344 if (String.IsNullOrEmpty (value)) 345 return; 346 347 ViewState ["NextPageImageUrl"] = value; 348 } 349 } 350 351 public string NextPageText { 352 get { 353 string s = ViewState ["NextPageText"] as string; 354 if (s != null) 355 return s; 356 357 return Default_NextPageText; 358 } 359 360 set { 361 if (String.IsNullOrEmpty (value) || String.Compare (Default_NextPageText, value, StringComparison.Ordinal) == 0) 362 return; 363 364 ViewState ["NextPageText"] = value; 365 } 366 } 367 368 public string NextPreviousButtonCssClass { 369 get { 370 string s = ViewState ["NextPreviousButtonCssClass"] as string; 371 if (s != null) 372 return s; 373 374 return String.Empty; 375 } 376 377 set { 378 if (String.IsNullOrEmpty (value)) 379 return; 380 381 ViewState ["NextPreviousButtonCssClass"] = value; 382 } 383 } 384 385 public string NumericButtonCssClass { 386 get { 387 string s = ViewState ["NumericButtonCssClass"] as string; 388 if (s != null) 389 return s; 390 391 return String.Empty; 392 } 393 394 set { 395 if (String.IsNullOrEmpty (value)) 396 return; 397 398 ViewState ["NumericButtonCssClass"] = value; 399 } 400 } 401 402 public string PreviousPageImageUrl { 403 get { 404 string s = ViewState ["PreviousPageImageUrl"] as string; 405 if (s != null) 406 return s; 407 408 return String.Empty; 409 } 410 411 set { 412 if (String.IsNullOrEmpty (value)) 413 return; 414 415 ViewState ["PreviousPageImageUrl"] = value; 416 } 417 } 418 419 public string PreviousPageText { 420 get { 421 string s = ViewState ["PreviousPageText"] as string; 422 if (s != null) 423 return s; 424 425 return Default_PreviousPageText; 426 } 427 428 set { 429 if (String.IsNullOrEmpty (value) || String.Compare (Default_PreviousPageText, value, StringComparison.Ordinal) == 0) 430 return; 431 432 ViewState ["PreviousPageText"] = value; 433 } 434 } 435 436 public bool RenderNonBreakingSpacesBetweenControls { 437 get { return _renderNonBreakingSpacesBetweenControls; } 438 set { _renderNonBreakingSpacesBetweenControls = value; } 439 } 440 } 441 } 442