2004-05-26 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / DataGrid.cs
1 //
2 // System.Web.UI.WebControls.DataGrid.cs
3 //
4 // Authors:
5 //   Gaurav Vaish (gvaish@iitk.ac.in)
6 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 //
8 // (C) Gaurav Vaish (2002)
9 // (C) 2003 Andreas Nahr
10 //
11
12 using System;
13 using System.Collections;
14 using System.Globalization;
15 using System.Web;
16 using System.Web.UI;
17 using System.Web.Util;
18 using System.ComponentModel;
19 using System.ComponentModel.Design;
20 using System.Reflection;
21
22 namespace System.Web.UI.WebControls
23 {
24         [Designer ("System.Web.UI.Design.WebControls.DataGridDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]\r
25         [Editor ("System.Web.UI.Design.WebControls.DataGridComponentEditor, " + Consts.AssemblySystem_Design, typeof (ComponentEditor))]
26         public class DataGrid : BaseDataList, INamingContainer
27         {
28                 public const string CancelCommandName       = "Cancel";
29                 public const string DeleteCommandName       = "Delete";
30                 public const string EditCommandName         = "Edit";
31                 public const string NextPageCommandArgument = "Next";
32                 public const string PageCommandName         = "Page";
33                 public const string PrevPageCommandArgument = "Prev";
34                 public const string SelectCommandName       = "Select";
35                 public const string SortCommandName         = "Sort";
36                 public const string UpdateCommandName       = "Update";
37
38                 private TableItemStyle alternatingItemStyle;
39                 private TableItemStyle editItemStyle;
40                 private TableItemStyle headerStyle;
41                 private TableItemStyle footerStyle;
42                 private TableItemStyle itemStyle;
43                 private TableItemStyle selectedItemStyle;
44                 private DataGridPagerStyle pagerStyle;
45
46                 private DataGridColumnCollection columns;
47                 private ArrayList                columnsArrayList;
48                 private DataGridItemCollection   items;
49                 private ArrayList                itemsArrayList;
50                 private PagedDataSource          pagedDataSource;
51
52                 private ArrayList   autoGenColsArrayList;
53                 private IEnumerator storedData;
54                 private object      storedDataFirst;
55                 private bool        storedDataValid;
56
57                 private static readonly object CancelCommandEvent    = new object();
58                 private static readonly object DeleteCommandEvent    = new object();
59                 private static readonly object EditCommandEvent      = new object();
60                 private static readonly object ItemCommandEvent      = new object();
61                 private static readonly object ItemCreatedEvent      = new object();
62                 private static readonly object ItemDataBoundEvent    = new object();
63                 private static readonly object PageIndexChangedEvent = new object();
64                 private static readonly object SortCommandEvent      = new object();
65                 private static readonly object UpdateCommandEvent    = new object();
66
67                 public DataGrid(): base()
68                 {
69                 }
70
71                 [DefaultValue (false), WebCategory ("Paging")]
72                 [WebSysDescription ("Allows custom paging.")]
73                 public virtual bool AllowCustomPaging
74                 {
75                         get
76                         {
77                                 object o = ViewState["AllowCustomPaging"];
78                                 if(o != null)
79                                         return (bool)o;
80                                 return false;
81                         }
82                         set
83                         {
84                                 ViewState["AllowCustomPaging"] = value;
85                         }
86                 }
87
88                 [DefaultValue (false), WebCategory ("Paging")]
89                 [WebSysDescription ("Allow using multiple pages.")]
90                 public virtual bool AllowPaging
91                 {
92                         get
93                         {
94                                 object o = ViewState["AllowPaging"];
95                                 if(o != null)
96                                         return (bool)o;
97                                 return false;
98                         }
99                         set
100                         {
101                                 ViewState["AllowPaging"] = value;
102                         }
103                 }
104
105                 [DefaultValue (false), WebCategory ("Behavior")]
106                 [WebSysDescription ("Allows the user to sort the table by clicking on column headers.")]
107                 public virtual bool AllowSorting
108                 {
109                         get
110                         {
111                                 object o = ViewState["AllowSorting"];
112                                 if(o != null)
113                                         return (bool)o;
114                                 return false;
115                         }
116                         set
117                         {
118                                 ViewState["AllowSorting"] = value;
119                         }
120                 }
121
122                 [NotifyParentProperty (true), WebCategory ("Style")]
123                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
124                 [PersistenceMode (PersistenceMode.InnerProperty)]
125                 [WebSysDescription ("The style applied to alternating items.")]
126                 public virtual TableItemStyle AlternatingItemStyle
127                 {
128                         get
129                         {
130                                 if(alternatingItemStyle == null)
131                                 {
132                                         alternatingItemStyle = new TableItemStyle();
133                                 }
134                                 if(IsTrackingViewState)
135                                 {
136                                         alternatingItemStyle.TrackViewState();
137                                 }
138                                 return alternatingItemStyle;
139                         }
140                 }
141
142                 [DefaultValue (true), WebCategory ("Behavior")]
143                 [WebSysDescription ("Automatically generate columns at runtime for each field found in the datasource.")]
144                 public virtual bool AutoGenerateColumns
145                 {
146                         get
147                         {
148                                 object o = ViewState["AutoGenerateColumns"];
149                                 if(o != null)
150                                         return (bool)o;
151                                 return true;
152                         }
153                         set
154                         {
155                                 ViewState["AutoGenerateColumns"] = value;
156                         }
157                 }
158
159                 [DefaultValue (""), Bindable (true), WebCategory ("Appearance")]
160                 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
161                 [WebSysDescription ("The URL to the image file used as background.")]
162                 public virtual string BackImageUrl
163                 {
164                         get
165                         {
166                                  if (!ControlStyleCreated)\r
167                                         return string.Empty; \r
168                                 return ((TableStyle) base.ControlStyle).BackImageUrl; 
169                         }
170                         set
171                         {
172                                  ((TableStyle) base.ControlStyle).BackImageUrl = value;
173                         }
174                 }
175
176                 [DefaultValue (true), WebCategory ("Behavior")]
177                 [PersistenceMode (PersistenceMode.InnerProperty)]
178                 [MergableProperty (false)]
179                 [Editor ("System.Web.UI.Design.WebControls.DataGridColumnCollectionEditor, " + Consts.AssemblySystem_Design, typeof (ComponentEditor))]
180                 [WebSysDescription ("Automatically generate columns at runtime for each field found in the datasource.")]
181                 public virtual DataGridColumnCollection Columns
182                 {
183                         get
184                         {
185                                 if(columns == null)
186                                 {
187                                         columnsArrayList = new ArrayList();
188                                         columns = new DataGridColumnCollection(this, columnsArrayList);
189                                         if(IsTrackingViewState)
190                                         {
191                                                 ((IStateManager)columns).TrackViewState();
192                                         }
193                                 }
194                                 return columns;
195                         }
196                 }
197
198                 [Browsable (false), Bindable (true)]
199                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
200                 [WebSysDescription ("The index number for the currently selected page.")]
201                 public int CurrentPageIndex
202                 {
203                         get
204                         {
205                                 object o = ViewState["CurrentPageIndex"];
206                                 if(o != null)
207                                         return (int)o;
208                                 return 0;
209                         }
210                         set
211                         {
212                                 if(value < 0)
213                                         throw new ArgumentOutOfRangeException ("value", "CurrentPageIndex value has to be 0 for 'not set' or > 0.");
214                                 ViewState["CurrentPageIndex"] = value;
215                         }
216                 }
217
218
219                 [DefaultValue (-1), WebCategory ("Misc")]
220                 [WebSysDescription ("The index number for the currently edited item.")]
221                 public virtual int EditItemIndex
222                 {
223                         get
224                         {
225                                 object o = ViewState["EditItemIndex"];
226                                 if(o != null)
227                                         return (int)o;
228                                 return -1;
229                         }
230                         set
231                         {
232                                 if(value < -1)
233                                         throw new ArgumentOutOfRangeException ("value", "EditItemIndex value has to be -1 for 'not set' or > -1.");
234                                 ViewState["EditItemIndex"] = value;
235                         }
236                 }
237
238                 [NotifyParentProperty (true), WebCategory ("Style")]
239                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
240                 [PersistenceMode (PersistenceMode.InnerProperty)]
241                 [WebSysDescription ("The style applied to items that are currently being edited.")]
242                 public virtual TableItemStyle EditItemStyle
243                 {
244                         get
245                         {
246                                 if(editItemStyle == null)
247                                 {
248                                         editItemStyle = new TableItemStyle();
249                                         if(IsTrackingViewState)
250                                         {
251                                                 editItemStyle.TrackViewState();
252                                         }
253                                 }
254                                 return editItemStyle;
255                         }
256                 }
257
258                 [DefaultValue (null), NotifyParentProperty (true), WebCategory ("Style")]
259                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
260                 [PersistenceMode (PersistenceMode.InnerProperty)]
261                 [WebSysDescription ("The style applied to the footer.")]
262                 public virtual TableItemStyle FooterStyle
263                 {
264                         get
265                         {
266                                 if(footerStyle == null)
267                                 {
268                                         footerStyle = new TableItemStyle();
269                                         if(IsTrackingViewState)
270                                         {
271                                                 footerStyle.TrackViewState();
272                                         }
273                                 }
274                                 return footerStyle;
275                         }
276                 }
277
278                 [DefaultValue (null), NotifyParentProperty (true), WebCategory ("Style")]
279                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
280                 [PersistenceMode (PersistenceMode.InnerProperty)]
281                 [WebSysDescription ("The style applied to the header.")]
282                 public virtual TableItemStyle HeaderStyle
283                 {
284                         get
285                         {
286                                 if(headerStyle == null)
287                                 {
288                                         headerStyle = new TableItemStyle();
289                                         if(IsTrackingViewState)
290                                         {
291                                                 headerStyle.TrackViewState();
292                                         }
293                                 }
294                                 return headerStyle;
295                         }
296                 }
297
298                 [Browsable (false)]
299                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
300                 [WebSysDescription ("A collection containing all items.")]
301                 public virtual DataGridItemCollection Items
302                 {
303                         get
304                         {
305                                 if(items == null)
306                                 {
307                                         if(itemsArrayList == null)
308                                                 EnsureChildControls();
309                                         if(itemsArrayList == null)
310                                         {
311                                                 itemsArrayList = new ArrayList();
312                                         }
313                                         items = new DataGridItemCollection(itemsArrayList);
314                                 }
315                                 return items;
316                         }
317                 }
318
319                 [NotifyParentProperty (true), WebCategory ("Style")]
320                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
321                 [PersistenceMode (PersistenceMode.InnerProperty)]
322                 [WebSysDescription ("The style applied to items.")]
323                 public virtual TableItemStyle ItemStyle
324                 {
325                         get
326                         {
327                                 if(itemStyle == null)
328                                 {
329                                         itemStyle = new TableItemStyle();
330                                         if(IsTrackingViewState)
331                                         {
332                                                 itemStyle.TrackViewState();
333                                         }
334                                 }
335                                 return itemStyle;
336                         }
337                 }
338
339                 [Browsable (false)]
340                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
341                 [WebSysDescription ("The number of pages.")]
342                 public int PageCount
343                 {
344                         get
345                         {
346                                 if(pagedDataSource != null)
347                                 {
348                                         return pagedDataSource.PageCount;
349                                 }
350                                 object o = ViewState["PageCount"];
351                                 if(o != null)
352                                         return (int)o;
353                                 return 0;
354                         }
355                 }
356
357                 [NotifyParentProperty (true), WebCategory ("Style")]
358                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
359                 [PersistenceMode (PersistenceMode.InnerProperty)]
360                 [WebSysDescription ("The style applied to the pager.")]
361                 public virtual DataGridPagerStyle PagerStyle
362                 {
363                         get
364                         {
365                                 if(pagerStyle == null)
366                                 {
367                                         pagerStyle = new DataGridPagerStyle(this);
368                                         if(IsTrackingViewState)
369                                         {
370                                                 pagerStyle.TrackViewState();
371                                         }
372                                 }
373                                 return pagerStyle;
374                         }
375                 }
376
377                 [DefaultValue (10), WebCategory ("Paging")]
378                 [WebSysDescription ("The maximum number of entries that are created per page.")]
379                 public virtual int PageSize
380                 {
381                         get
382                         {
383                                 object o = ViewState["PageSize"];
384                                 if(o != null)
385                                         return (int)o;
386                                 return 10;
387                         }
388                         set
389                         {
390                                 if(value < 1)
391                                         throw new ArgumentOutOfRangeException();
392                                 ViewState["PageSize"] = value;
393                         }
394                 }
395
396                 [DefaultValue (-1), Bindable (true)]
397                 [WebSysDescription ("The index number for the currently selected item.")]
398                 public virtual int SelectedIndex
399                 {
400                         get
401                         {
402                                 object o = ViewState["SelectedIndex"];
403                                 if(o != null)
404                                         return (int)o;
405                                 return -1;
406                         }
407                         set
408                         {
409                                 if(value < -1)
410                                         throw new ArgumentOutOfRangeException();
411                                 int prevVal = SelectedIndex;
412                                 ViewState["SelectedIndex"] = value;
413                                 if (itemsArrayList != null) {
414                                         if (prevVal !=-1 && prevVal < itemsArrayList.Count) {
415                                                 DataGridItem prev = (DataGridItem)itemsArrayList[prevVal];
416                                                 if(prev.ItemType != ListItemType.EditItem)
417                                                 {
418                                                         ListItemType newType = ListItemType.Item;
419                                                         if( (prevVal % 2) != 0)
420                                                         {
421                                                                 newType = ListItemType.AlternatingItem;
422                                                         }
423                                                         prev.SetItemType(newType);
424                                                 }
425                                         }
426
427                                         if (value != -1 && itemsArrayList.Count > value) {
428                                                 DataGridItem itemToSelect = (DataGridItem) itemsArrayList [value];
429                                                 if (itemToSelect.ItemType != ListItemType.EditItem) {
430                                                         itemToSelect.SetItemType (ListItemType.SelectedItem);
431                                                 }
432                                         }
433                                 }
434                         }
435                 }
436
437                 [Browsable (false)]
438                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
439                 [WebSysDescription ("The currently selected item.")]
440                 public virtual DataGridItem SelectedItem
441                 {
442                         get
443                         {
444                                 if(SelectedIndex == -1)
445                                         return null;
446                                 return Items[SelectedIndex];
447                         }
448                 }
449
450                 [NotifyParentProperty (true), WebCategory ("Style")]
451                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
452                 [PersistenceMode (PersistenceMode.InnerProperty)]
453                 [WebSysDescription ("The style applied to the currently selected item.")]
454                 public virtual TableItemStyle SelectedItemStyle
455                 {
456                         get
457                         {
458                                 if(selectedItemStyle == null)
459                                 {
460                                         selectedItemStyle = new TableItemStyle();
461                                         if(IsTrackingViewState)
462                                         {
463                                                 selectedItemStyle.TrackViewState();
464                                         }
465                                 }
466                                 return selectedItemStyle;
467                         }
468                 }
469
470                 [DefaultValue (false), Bindable (true), WebCategory ("Appearance")]
471                 [WebSysDescription ("Determines if the footer should be shown.")]
472                 public virtual bool ShowFooter
473                 {
474                         get
475                         {
476                                 object o = ViewState["ShowFooter"];
477                                 if(o != null)
478                                         return (bool)o;
479                                 return false;
480                         }
481                         set
482                         {
483                                 ViewState["ShowFooter"] = value;
484                         }
485                 }
486
487                 [DefaultValue (false), Bindable (true), WebCategory ("Appearance")]
488                 [WebSysDescription ("Determines if the header should be shown.")]
489                 public virtual bool ShowHeader
490                 {
491                         get
492                         {
493                                 object o = ViewState["ShowHeader"];
494                                 if(o != null)
495                                         return (bool)o;
496                                 return true;
497                         }
498                         set
499                         {
500                                 ViewState["ShowHeader"] = value;
501                         }
502                 }
503
504                 [Browsable (false)]
505                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
506                 [WebSysDescription ("The number of items that are visible.")]
507                 public virtual int VirtualItemCount
508                 {
509                         get
510                         {
511                                 object o = ViewState["VirtualItemCount"];
512                                 if(o != null)
513                                         return (int)o;
514                                 return 0;
515                         }
516                         set
517                         {
518                                 if(value < 0)
519                                         throw new ArgumentOutOfRangeException ("value", "VirtualItemCount value has to be >= 0.");
520                                 ViewState["VirtualItemCount"] = value;
521                         }
522                 }
523
524                 [WebCategory ("Action")]
525                 [WebSysDescription ("Raised when a cancel command is generated.")]
526                 public event DataGridCommandEventHandler CancelCommand
527                 {
528                         add
529                         {
530                                 Events.AddHandler(CancelCommandEvent, value);
531                         }
532                         remove
533                         {
534                                 Events.RemoveHandler(CancelCommandEvent, value);
535                         }
536                 }
537
538                 [WebCategory ("Action")]
539                 [WebSysDescription ("Raised when a delete command is generated.")]
540                 public event DataGridCommandEventHandler DeleteCommand
541                 {
542                         add
543                         {
544                                 Events.AddHandler(DeleteCommandEvent, value);
545                         }
546                         remove
547                         {
548                                 Events.RemoveHandler(DeleteCommandEvent, value);
549                         }
550                 }
551
552                 [WebCategory ("Action")]
553                 [WebSysDescription ("Raised when an edit command is generated.")]
554                 public event DataGridCommandEventHandler EditCommand
555                 {
556                         add
557                         {
558                                 Events.AddHandler(EditCommandEvent, value);
559                         }
560                         remove
561                         {
562                                 Events.RemoveHandler(EditCommandEvent, value);
563                         }
564                 }
565
566                 [WebCategory ("Action")]
567                 [WebSysDescription ("Raised when an item command is generated.")]
568                 public event DataGridCommandEventHandler ItemCommand
569                 {
570                         add
571                         {
572                                 Events.AddHandler(ItemCommandEvent, value);
573                         }
574                         remove
575                         {
576                                 Events.RemoveHandler(ItemCommandEvent, value);
577                         }
578                 }
579
580                 [WebCategory ("Behavior")]
581                 [WebSysDescription ("Raised when a new item is created.")]
582                 public event DataGridItemEventHandler ItemCreated
583                 {
584                         add
585                         {
586                                 Events.AddHandler(ItemCreatedEvent, value);
587                         }
588                         remove
589                         {
590                                 Events.RemoveHandler(ItemCreatedEvent, value);
591                         }
592                 }
593
594                 [WebCategory ("Behavior")]
595                 [WebSysDescription ("Raised when a item gets data-bound.")]
596                 public event DataGridItemEventHandler ItemDataBound
597                 {
598                         add
599                         {
600                                 Events.AddHandler(ItemDataBoundEvent, value);
601                         }
602                         remove
603                         {
604                                 Events.RemoveHandler(ItemDataBoundEvent, value);
605                         }
606                 }
607
608                 [WebCategory ("Action")]
609                 [WebSysDescription ("Raised when the currently selected page changes.")]
610                 public event DataGridPageChangedEventHandler PageIndexChanged
611                 {
612                         add
613                         {
614                                 Events.AddHandler(PageIndexChangedEvent, value);
615                         }
616                         remove
617                         {
618                                 Events.RemoveHandler(PageIndexChangedEvent, value);
619                         }
620                 }
621
622                 [WebCategory ("Action")]
623                 [WebSysDescription ("Raised when a sort command is generated.")]
624                 public event DataGridSortCommandEventHandler SortCommand
625                 {
626                         add
627                         {
628                                 Events.AddHandler(SortCommandEvent, value);
629                         }
630                         remove
631                         {
632                                 Events.RemoveHandler(SortCommandEvent, value);
633                         }
634                 }
635
636                 [WebCategory ("Action")]
637                 [WebSysDescription ("Raised when an update command is generated.")]
638                 public event DataGridCommandEventHandler UpdateCommand
639                 {
640                         add
641                         {
642                                 Events.AddHandler(UpdateCommandEvent, value);
643                         }
644                         remove
645                         {
646                                 Events.RemoveHandler(UpdateCommandEvent, value);
647                         }
648                 }
649
650                 protected override Style CreateControlStyle()
651                 {
652                         TableStyle style = new TableStyle(ViewState);
653                         style.GridLines = GridLines.Both;
654                         style.CellSpacing = 0;
655                         return style;
656                 }
657
658                 protected override void LoadViewState(object savedState)
659                 {
660                         if (savedState == null)
661                                 return;
662
663                         object [] states = (object []) savedState;
664                         base.LoadViewState (states[0]);
665                         if(columns != null)
666                                 ((IStateManager)columns).LoadViewState(states[1]);
667                         if(pagerStyle != null)
668                                 pagerStyle.LoadViewState(states[2]);
669                         if(headerStyle != null)
670                                 headerStyle.LoadViewState(states[3]);
671                         if(footerStyle != null)
672                                 footerStyle.LoadViewState(states[4]);
673                         if(itemStyle != null)
674                                 itemStyle.LoadViewState(states[5]);
675                         if(alternatingItemStyle != null)
676                                 alternatingItemStyle.LoadViewState(states[6]);
677                         if(selectedItemStyle != null)
678                                 selectedItemStyle.LoadViewState(states[7]);
679                         if(editItemStyle != null)
680                                 editItemStyle.LoadViewState(states[8]);
681
682                         if (states [9] != null) {
683                                 object[] array = ((object[]) states [9]);
684                                 if (array.Length != 0)
685                                         this.autoGenColsArrayList = new ArrayList ();
686                                 else
687                                         this.autoGenColsArrayList = null; 
688
689                                 for (int i = 0; i < array.Length; i++) {
690                                         BoundColumn column1 = new BoundColumn ();
691                                         ((IStateManager)column1).TrackViewState ();
692                                         ((IStateManager)column1).LoadViewState (array [i]);
693                                         column1.SetOwner (this);
694                                         this.autoGenColsArrayList.Add (column1);
695                                 } 
696                         }
697                 }
698
699                 protected override object SaveViewState()
700                 {
701                         object[] states = new object [10];
702                         states[0] = base.SaveViewState();
703                         states[1] = (columns == null ? null : ((IStateManager)columns).SaveViewState());
704                         states[2] = (pagerStyle == null ? null : pagerStyle.SaveViewState());
705                         states[3] = (headerStyle == null ? null : headerStyle.SaveViewState());
706                         states[4] = (footerStyle == null ? null : footerStyle.SaveViewState());
707                         states[5] = (itemStyle == null ? null : itemStyle.SaveViewState());
708                         states[6] = (alternatingItemStyle == null ? null : alternatingItemStyle.SaveViewState());
709                         states[7] = (selectedItemStyle == null ? null : selectedItemStyle.SaveViewState());
710                         states[8] = (editItemStyle == null ? null : editItemStyle.SaveViewState());
711
712                         object [] array = null;
713                         if ((this.autoGenColsArrayList != null) && (this.autoGenColsArrayList.Count != 0)) {
714                                 array = new object [((uint) this.autoGenColsArrayList.Count)];
715                                 for (int i = 0; i < array.Length; i++)
716                                         array [i] = ((IStateManager) this.autoGenColsArrayList [i]).SaveViewState ();
717                         }
718
719                         states [9] = array;
720
721                         for (int i = states.Length - 1; i >= 0; i--) {
722                                 if (states [i] != null)
723                                         return states;
724                         }
725
726                         return null;
727                 }
728
729                 protected override void TrackViewState()
730                 {
731                         base.TrackViewState();
732                         if(alternatingItemStyle != null)
733                         {
734                                 alternatingItemStyle.TrackViewState();
735                         }
736                         if(editItemStyle != null)
737                         {
738                                 editItemStyle.TrackViewState();
739                         }
740                         if(headerStyle != null)
741                         {
742                                 headerStyle.TrackViewState();
743                         }
744                         if(footerStyle != null)
745                         {
746                                 footerStyle.TrackViewState();
747                         }
748                         if(itemStyle != null)
749                         {
750                                 itemStyle.TrackViewState();
751                         }
752                         if(selectedItemStyle != null)
753                         {
754                                 selectedItemStyle.TrackViewState();
755                         }
756                         if(pagerStyle != null)
757                         {
758                                 pagerStyle.TrackViewState();
759                         }
760
761                         if(columns != null)
762                         {
763                                 ((IStateManager)columns).TrackViewState();
764                         }
765                 }
766
767                 protected override bool OnBubbleEvent(object source, EventArgs e)
768                 {
769                         bool retVal = false;
770                         if(e is DataGridCommandEventArgs)
771                         {
772                                 DataGridCommandEventArgs ea = (DataGridCommandEventArgs)e;
773                                 retVal = true;
774                                 OnItemCommand(ea);
775                                 string cmd = ea.CommandName;
776                                 if(String.Compare(cmd, "select", true) == 0)
777                                 {
778                                         SelectedIndex = ea.Item.ItemIndex;
779                                         OnSelectedIndexChanged(EventArgs.Empty);
780                                 } else if(String.Compare(cmd,"page", true) == 0)
781                                 {
782                                         int    cIndex = CurrentPageIndex;
783                                         string cea = (string) ea.CommandArgument;
784                                         if(String.Compare(cea, "prev", true) == 0)
785                                         {
786                                                 cIndex--;
787                                         } else if(String.Compare(cea, "next", true) == 0)
788                                         {
789                                                 cIndex++;
790                                         } else {
791                                                 cIndex = Convert.ToInt32 (cea) - 1;
792                                         }
793
794                                         OnPageIndexChanged(new DataGridPageChangedEventArgs(source, cIndex));
795                                 } else if(String.Compare(cmd, "sort", true) == 0)
796                                 {
797                                         OnSortCommand(new DataGridSortCommandEventArgs(source, ea));
798                                 } else if(String.Compare(cmd, "edit", true) == 0)
799                                 {
800                                         OnEditCommand(ea);
801                                 } else if(String.Compare(cmd, "update", true) == 0)
802                                 {
803                                         OnUpdateCommand(ea);
804                                 } else if(String.Compare(cmd, "cancel", true) == 0)
805                                 {
806                                         OnCancelCommand(ea);
807                                 } else if(String.Compare(cmd, "delete", true) == 0)
808                                 {
809                                         OnDeleteCommand(ea);
810                                 }
811                         }
812                         return retVal;
813                 }
814
815                 protected virtual void OnCancelCommand(DataGridCommandEventArgs e)
816                 {
817                         if(Events != null)
818                         {
819                                 DataGridCommandEventHandler dceh = (DataGridCommandEventHandler)(Events[CancelCommandEvent]);
820                                 if(dceh != null)
821                                         dceh(this, e);
822                         }
823                 }
824
825                 protected virtual void OnDeleteCommand(DataGridCommandEventArgs e)
826                 {
827                         if(Events != null)
828                         {
829                                 DataGridCommandEventHandler dceh = (DataGridCommandEventHandler)(Events[DeleteCommandEvent]);
830                                 if(dceh != null)
831                                         dceh(this, e);
832                         }
833                 }
834
835                 protected virtual void OnEditCommand(DataGridCommandEventArgs e)
836                 {
837                         if(Events != null)
838                         {
839                                 DataGridCommandEventHandler dceh = (DataGridCommandEventHandler)(Events[EditCommandEvent]);
840                                 if(dceh != null)
841                                         dceh(this, e);
842                         }
843                 }
844
845                 protected virtual void OnItemCommand(DataGridCommandEventArgs e)
846                 {
847                         if(Events != null)
848                         {
849                                 DataGridCommandEventHandler dceh = (DataGridCommandEventHandler)(Events[ItemCommandEvent]);
850                                 if(dceh != null)
851                                         dceh(this, e);
852                         }
853                 }
854
855                 protected virtual void OnItemCreated(DataGridItemEventArgs e)
856                 {
857                         if(Events != null)
858                         {
859                                 DataGridItemEventHandler dceh = (DataGridItemEventHandler)(Events[ItemCreatedEvent]);
860                                 if(dceh != null)
861                                         dceh(this, e);
862                         }
863                 }
864
865                 protected virtual void OnItemDataBound(DataGridItemEventArgs e)
866                 {
867                         if(Events != null)
868                         {
869                                 DataGridItemEventHandler dceh = (DataGridItemEventHandler)(Events[ItemDataBoundEvent]);
870                                 if(dceh != null)
871                                         dceh(this, e);
872                         }
873                 }
874
875                 protected virtual void OnPageIndexChanged(DataGridPageChangedEventArgs e)
876                 {
877                         if(Events != null)
878                         {
879                                 DataGridPageChangedEventHandler dceh = (DataGridPageChangedEventHandler)(Events[PageIndexChangedEvent]);
880                                 if(dceh != null)
881                                         dceh(this, e);
882                         }
883                 }
884
885                 protected virtual void OnSortCommand(DataGridSortCommandEventArgs e)
886                 {
887                         if(Events != null)
888                         {
889                                 DataGridSortCommandEventHandler dceh = (DataGridSortCommandEventHandler)(Events[SortCommandEvent]);
890                                 if(dceh != null)
891                                         dceh(this, e);
892                         }
893                 }
894
895                 protected virtual void OnUpdateCommand(DataGridCommandEventArgs e)
896                 {
897                         if(Events != null)
898                         {
899                                 DataGridCommandEventHandler dceh = (DataGridCommandEventHandler)(Events[UpdateCommandEvent]);
900                                 if(dceh != null)
901                                         dceh(this, e);
902                         }
903                 }
904
905                 protected override void PrepareControlHierarchy()
906                 {
907                         if (Controls.Count == 0)
908                                 return;
909
910                         Table display = (Table) Controls [0];
911                         display.CopyBaseAttributes (this);
912                         if (ControlStyleCreated) {
913                                 display.ApplyStyle (ControlStyle);
914                         } else {
915                                 display.GridLines   = GridLines.Both;
916                                 display.CellSpacing = 0;
917                         }
918
919                         TableRowCollection rows = display.Rows;
920                         if (rows.Count == 0)
921                                 return;
922
923                         int nCols = Columns.Count;
924                         DataGridColumn [] cols = new DataGridColumn [nCols];
925                         Style deployStyle = null;
926
927                         if (nCols > 0)
928                                 Columns.CopyTo (cols, 0);
929
930                         if (alternatingItemStyle != null) {
931                                 deployStyle = new TableItemStyle ();
932                                 deployStyle.CopyFrom (itemStyle);
933                                 deployStyle.CopyFrom (alternatingItemStyle);
934                         } else {
935                                 deployStyle = itemStyle;
936                         }
937
938                         int nrows = rows.Count;
939                         for (int counter = 0; counter < nrows; counter++)
940                                 PrepareControlHierarchyForItem (cols,
941                                                                 (DataGridItem) rows [counter],
942                                                                 counter,
943                                                                 deployStyle);
944                 }
945
946                 private void PrepareControlHierarchyForItem (DataGridColumn [] cols,
947                                                              DataGridItem item,
948                                                              int index,
949                                                              Style deployStyle)
950                 {
951                         switch (item.ItemType) {
952                         case ListItemType.Header:
953                                 if (!ShowHeader) {
954                                         item.Visible = false;
955                                         break;
956                                 }
957
958                                 if (headerStyle != null)
959                                         item.MergeStyle (headerStyle);
960
961                                 goto case ListItemType.Separator;
962                         case ListItemType.Footer:
963                                 if (!ShowFooter) {
964                                         item.Visible = false;
965                                         break;
966                                 }
967
968                                 if (footerStyle != null)
969                                         item.MergeStyle (footerStyle);
970
971                                 goto case ListItemType.Separator;
972                         case ListItemType.Item  :
973                                 item.MergeStyle (itemStyle);
974                                 goto case ListItemType.Separator;
975                         case ListItemType.AlternatingItem:
976                                 item.MergeStyle (deployStyle);
977                                 goto case ListItemType.Separator;
978                         case ListItemType.SelectedItem:
979                                 Style selStyle = new TableItemStyle ();
980                                 if ((item.ItemIndex % 2) == 0) {
981                                         selStyle.CopyFrom (itemStyle);
982                                 } else {
983                                         selStyle.CopyFrom (deployStyle);
984                                 }
985
986                                 selStyle.CopyFrom (selectedItemStyle);
987                                 item.MergeStyle (selStyle);
988                                 goto case ListItemType.Separator;
989                         case ListItemType.EditItem:
990                                 Style edStyle = new TableItemStyle ();
991                                 if ((item.ItemIndex % 2) == 0) {
992                                         edStyle.CopyFrom (itemStyle);
993                                 } else {
994                                         edStyle.CopyFrom (deployStyle);
995                                 }
996
997                                 edStyle.CopyFrom (editItemStyle);
998                                 item.MergeStyle (edStyle);
999                                 goto case ListItemType.Separator;
1000                         case ListItemType.Pager:
1001                                 if (pagerStyle == null)
1002                                         break;
1003
1004                                 if (!pagerStyle.Visible)
1005                                         item.Visible = false;
1006
1007                                 if (index == 0) {
1008                                         if (!pagerStyle.IsPagerOnTop) {
1009                                                 item.Visible = false;
1010                                                 break;
1011                                         }
1012                                 } else if (!pagerStyle.IsPagerOnBottom) {
1013                                         item.Visible = false;
1014                                         break;
1015                                 }
1016
1017                                 item.MergeStyle (pagerStyle);
1018                                 goto case ListItemType.Separator;
1019                         case ListItemType.Separator:
1020                                 TableCellCollection cells = item.Cells;
1021                                 int cellCount = cells.Count;
1022                                 if (cellCount > cols.Length)
1023                                         cellCount = cols.Length;
1024
1025                                 if (cellCount > 0 && item.ItemType != ListItemType.Pager) {
1026                                         for (int i = 0; i < cellCount; i++) {
1027                                                 Style colStyle = null;
1028                                                 if (cols [i].Visible) {
1029                                                         switch (item.ItemType) {
1030                                                         case ListItemType.Header:
1031                                                                 colStyle = cols [i].HeaderStyleInternal;
1032                                                                 break;
1033                                                         case ListItemType.Footer:
1034                                                                 colStyle = cols [i].FooterStyleInternal;
1035                                                                 break;
1036                                                         default:
1037                                                                 colStyle = cols [i].ItemStyleInternal;
1038                                                                 break;
1039                                                         }
1040                                                         cells[i].MergeStyle (colStyle);
1041                                                 } else {
1042                                                         cells [i].Visible = false;
1043                                                 }
1044                                         }
1045                                 }
1046                                 break;
1047                         default:
1048                                 goto case ListItemType.Separator;
1049                         }
1050                 }
1051
1052                 protected override void CreateControlHierarchy(bool useDataSource)
1053                 {
1054                         IEnumerator pageSourceEnumerator;
1055                         int         itemCount;
1056                         ArrayList   dataKeys;
1057                         ArrayList   columns;
1058                         IEnumerable resolvedDS;
1059                         ICollection collResolvedDS;
1060                         int         pageDSCount;
1061                         int         colCount;
1062                         DataGridColumn[] cols;
1063                         Table       deployTable;
1064                         TableRowCollection deployRows;
1065                         ListItemType deployType;
1066                         int         indexCounter;
1067                         string      dkField;
1068                         bool        dsUse;
1069                         bool        pgEnabled;
1070                         int         editIndex;
1071                         int         selIndex;
1072
1073                         pagedDataSource = CreatePagedDataSource();
1074                         pageSourceEnumerator  = null;
1075                         itemCount       = -1;
1076                         dataKeys        = DataKeysArray;
1077                         columns         = null;
1078                         if(itemsArrayList != null)
1079                         {
1080                                 itemsArrayList.Clear();
1081                         } else
1082                         {
1083                                 itemsArrayList = new ArrayList();
1084                         }
1085                         if(!useDataSource)
1086                         {
1087                                 itemCount    = (int) ViewState["_!ItemCount"];
1088                                 pageDSCount  = (int) ViewState["_!DataSource_ItemCount"];
1089                                 if(itemCount != -1)
1090                                 {
1091                                         if(pagedDataSource.IsCustomPagingEnabled)
1092                                         {
1093                                                 pagedDataSource.DataSource = new DataSourceInternal(itemCount);
1094                                         } else
1095                                         {
1096                                                 pagedDataSource.DataSource = new DataSourceInternal(pageDSCount);
1097                                         }
1098                                         pageSourceEnumerator = pagedDataSource.GetEnumerator();
1099                                         columns              = CreateColumnSet(null, false);
1100                                         itemsArrayList.Capacity = itemCount;
1101                                 }
1102                         } else
1103                         {
1104                                 dataKeys.Clear();
1105                                 resolvedDS = GetResolvedDataSource ();
1106                                 if(resolvedDS != null)
1107                                 {
1108                                         collResolvedDS = resolvedDS as ICollection;
1109                                         if(pagedDataSource.IsPagingEnabled && !pagedDataSource.IsCustomPagingEnabled
1110                                            && collResolvedDS == null)
1111                                         {
1112                                                 throw new HttpException(HttpRuntime.FormatResourceString("DataGrid_Missing_VirtualItemCount", ID));
1113                                         }
1114                                         pagedDataSource.DataSource = resolvedDS;
1115                                         if(pagedDataSource.IsPagingEnabled && (pagedDataSource.CurrentPageIndex < 0 ||
1116                                                         pagedDataSource.PageCount < pagedDataSource.CurrentPageIndex))
1117                                         {
1118                                                 throw new HttpException(HttpRuntime.FormatResourceString("DataGrid_Invalid_Current_PageIndex", ID));
1119                                         }
1120                                         columns = CreateColumnSet(pagedDataSource, useDataSource);
1121
1122                                         if(storedDataValid)
1123                                         {
1124                                                 pageSourceEnumerator = storedData;
1125                                         } else
1126                                         {
1127                                                 pageSourceEnumerator = pagedDataSource.GetEnumerator();
1128                                         }
1129                                         if(collResolvedDS != null)
1130                                         {
1131                                                 pageDSCount         = pagedDataSource.Count;
1132                                                 dataKeys.Capacity   = pageDSCount;
1133                                                 itemsArrayList.Capacity = pageDSCount;
1134                                         }
1135                                 }
1136                         }
1137
1138                         colCount = 0;
1139                         if(columns != null)
1140                                 colCount = columns.Count;
1141                         int currentSourceIndex;
1142                         if(colCount > 0)
1143                         {
1144                                 cols = (DataGridColumn []) columns.ToArray (typeof (DataGridColumn));
1145                                 foreach(DataGridColumn current in cols)
1146                                 {
1147                                         current.Initialize();
1148                                 }
1149                                 deployTable = new DataGridTableInternal();
1150                                 Controls.Add(deployTable);
1151                                 deployRows = deployTable.Rows;
1152
1153                                 indexCounter = 0;
1154                                 currentSourceIndex  = 0;
1155                                 dkField = DataKeyField;
1156
1157                                 dsUse = (useDataSource) ? (dkField.Length > 0) : false;
1158                                 pgEnabled = pagedDataSource.IsPagingEnabled;
1159                                 editIndex = EditItemIndex;
1160                                 selIndex  = SelectedIndex;
1161                                 if(pgEnabled)
1162                                 {
1163                                         currentSourceIndex = pagedDataSource.FirstIndexInPage;
1164                                         CreateItem(-1, -1, ListItemType.Pager, false, null,
1165                                                    cols, deployRows, pagedDataSource);
1166                                 }
1167                                 itemCount = 0;
1168                                 CreateItem(-1, -1, ListItemType.Header, useDataSource, null,
1169                                            cols, deployRows, null);
1170                                 
1171                                 if(storedDataValid && storedDataFirst != null)
1172                                 {
1173                                         if(dsUse)
1174                                         {
1175                                                 dataKeys.Add(DataBinder.GetPropertyValue(storedDataFirst, dkField));
1176                                         }
1177                                         if (indexCounter == editIndex) {
1178                                                 deployType = ListItemType.EditItem;
1179                                         } else if (indexCounter == selIndex) {
1180                                                 deployType = ListItemType.SelectedItem;
1181                                         } else {
1182                                                 deployType = ListItemType.Item;
1183                                         }
1184
1185                                         itemsArrayList.Add(CreateItem(0, currentSourceIndex, deployType,
1186                                                                       useDataSource, storedDataFirst,
1187                                                                       cols, deployRows, null));
1188                                         itemCount++;
1189                                         indexCounter++;
1190                                         currentSourceIndex++;
1191                                         storedDataValid = false;
1192                                         storedDataFirst = null;
1193                                 }
1194
1195                                 while(pageSourceEnumerator.MoveNext())
1196                                 {
1197                                         object current = pageSourceEnumerator.Current;
1198                                         if(dsUse)
1199                                         {
1200                                                 dataKeys.Add(DataBinder.GetPropertyValue(current, dkField));
1201                                         }
1202
1203                                         if (indexCounter == editIndex) {
1204                                                 deployType = ListItemType.EditItem;
1205                                         } else if (indexCounter == selIndex) {
1206                                                 deployType = ListItemType.SelectedItem;
1207                                         } else if ((indexCounter % 2) == 1) {
1208                                                 deployType = ListItemType.AlternatingItem;
1209                                         } else {
1210                                                 deployType = ListItemType.Item;
1211                                         }
1212
1213                                         itemsArrayList.Add(CreateItem(indexCounter, currentSourceIndex,
1214                                                                       deployType, useDataSource, current,
1215                                                                       cols, deployRows, null));
1216                                         itemCount++;
1217                                         indexCounter++;
1218                                         currentSourceIndex++;
1219                                 }
1220
1221                                 CreateItem(-1, -1, ListItemType.Footer, useDataSource, null,
1222                                            cols, deployRows, null);
1223
1224                                 if(pgEnabled)
1225                                 {
1226                                         CreateItem(-1, -1, ListItemType.Pager, false, null, cols, deployRows,
1227                                                    pagedDataSource);
1228                                 }
1229                         }
1230
1231                         if(useDataSource)
1232                         {
1233                                 if(pageSourceEnumerator != null)
1234                                 {
1235                                         ViewState["_!ItemCount"] = itemCount;
1236                                         if(pagedDataSource.IsPagingEnabled)
1237                                         {
1238                                                 ViewState["PageCount"] = pagedDataSource.PageCount;
1239                                                 ViewState["_!DataSource_ItemCount"] = pagedDataSource.DataSourceCount;
1240                                         } else
1241                                         {
1242                                                 ViewState["PageCount"] = 1;
1243                                                 ViewState["_!DataSource_ItemCount"] = itemCount;
1244                                         }
1245                                 } else
1246                                 {
1247                                         ViewState["_!ItemCount"] = -1;
1248                                         ViewState["_!DataSource_ItemCount"] = -1;
1249                                         ViewState["PageCount"] = 0;
1250                                 }
1251                         }
1252                         pagedDataSource = null;
1253                 }
1254
1255                 private DataGridItem CreateItem(int itemIndex, int dsIndex, ListItemType type,
1256                                                 bool bind, object item, DataGridColumn[] columns,
1257                                                 TableRowCollection rows, PagedDataSource dataSrc)
1258
1259                 {
1260                         DataGridItem retVal;
1261                         DataGridItemEventArgs args;
1262
1263                         retVal = CreateItem(itemIndex, dsIndex, type);
1264                         args = new DataGridItemEventArgs(retVal);
1265
1266                         if(type != ListItemType.Pager)
1267                         {
1268                                 InitializeItem(retVal, columns);
1269                                 if(bind)
1270                                 {
1271                                         retVal.DataItem = item;
1272                                 }
1273                                 OnItemCreated(args);
1274                                 rows.Add(retVal);
1275                                 if(bind)
1276                                 {
1277                                         retVal.DataBind();
1278                                         OnItemDataBound(args);
1279                                         retVal.DataItem = null;
1280                                 }
1281                         } else
1282                         {
1283                                 InitializePager(retVal, columns.Length, dataSrc);
1284                                 OnItemCreated(args);
1285                                 rows.Add(retVal);
1286                         }
1287                         return retVal;
1288                 }
1289
1290                 protected virtual DataGridItem CreateItem(int itemIndex, int dataSourceIndex, ListItemType itemType)
1291                 {
1292                         return new DataGridItem(itemIndex, dataSourceIndex, itemType);
1293                 }
1294
1295                 protected virtual void InitializeItem(DataGridItem item, DataGridColumn[] columns)
1296                 {
1297                         TableCellCollection cells = item.Cells;
1298                         TableCell cCell;
1299                         
1300                         for(int i = 0; i < columns.Length; i++)
1301                         {
1302                                 cCell = new TableCell();
1303                                 columns[i].InitializeCell(cCell, i, item.ItemType);
1304                                 cells.Add(cCell);
1305                         }
1306                 }
1307
1308                 protected virtual void InitializePager(DataGridItem item,
1309                                        int columnSpan, PagedDataSource pagedDataSource)
1310                 {
1311                         TableCell toAdd = new TableCell();
1312                         toAdd.ColumnSpan = columnSpan;
1313                         
1314                         if(PagerStyle.Mode == PagerMode.NextPrev)
1315                         {
1316                                 if(!pagedDataSource.IsFirstPage)
1317                                 {
1318                                         LinkButton link = new DataGridLinkButton();
1319                                         link.Text = PagerStyle.PrevPageText;
1320                                         link.CommandName = "Page";
1321                                         link.CommandArgument = "Prev";
1322                                         link.CausesValidation = false;
1323                                         toAdd.Controls.Add(link);
1324                                 } else
1325                                 {
1326                                         Label label = new Label();
1327                                         label.Text = PagerStyle.PrevPageText;
1328                                         toAdd.Controls.Add(label);
1329                                 }
1330                                 toAdd.Controls.Add(new LiteralControl("&nbsp;"));
1331                                 
1332                                 if (pagedDataSource.PageCount == 0) {
1333                                         Label label = new Label();
1334                                         label.Text = PagerStyle.NextPageText;
1335                                         toAdd.Controls.Add(label);
1336                                 } else {                                
1337                                         if(!pagedDataSource.IsLastPage)
1338                                         {
1339                                                 LinkButton link = new DataGridLinkButton();
1340                                                 link.Text = PagerStyle.NextPageText;
1341                                                 link.CommandName = "Page";
1342                                                 link.CommandArgument = "Next";
1343                                                 link.CausesValidation = false;
1344                                                 toAdd.Controls.Add(link);
1345                                         } else
1346                                         {
1347                                                 Label label = new Label();
1348                                                 label.Text = PagerStyle.NextPageText;
1349                                                 toAdd.Controls.Add(label);
1350                                         }
1351                                 }
1352                         } else
1353                         {
1354                                 int pageCount = pagedDataSource.PageCount;
1355                                 int currPage  = pagedDataSource.CurrentPageIndex + 1;
1356                                 int btnCount  = PagerStyle.PageButtonCount;
1357                                 int numberOfPages = btnCount;
1358                                 if(numberOfPages > pageCount)
1359                                         numberOfPages = pageCount;
1360                                 int firstPageNumber = 1; // 10
1361                                 int lastPageNumber  = numberOfPages; // 11
1362
1363                                 if(currPage > lastPageNumber)
1364                                 {
1365                                         firstPageNumber = (pagedDataSource.CurrentPageIndex / btnCount) * btnCount + 1;
1366                                         lastPageNumber  = firstPageNumber + btnCount - 1;
1367                                         if(lastPageNumber > pageCount)
1368                                                 lastPageNumber = pageCount;
1369                                         if((lastPageNumber - firstPageNumber + 1) < btnCount)
1370                                                 firstPageNumber = Math.Max(1, lastPageNumber - btnCount + 1);
1371                                 }
1372                                 if(firstPageNumber != 1)
1373                                 {
1374                                         LinkButton toAddBtn = new DataGridLinkButton();
1375                                         toAddBtn.Text = "...";
1376                                         toAddBtn.CommandName = "Page";
1377                                         toAddBtn.CommandArgument = (firstPageNumber - 1).ToString(NumberFormatInfo.InvariantInfo);
1378                                         toAddBtn.CausesValidation = false;
1379                                         toAdd.Controls.Add(toAddBtn);
1380                                         toAdd.Controls.Add(new LiteralControl("&nbsp;"));
1381                                 }
1382                                 if (lastPageNumber == 0) {
1383                                         Label cPageLabel = new Label();
1384                                         cPageLabel.Text = "1";
1385                                         toAdd.Controls.Add(cPageLabel);
1386                                 } else {
1387                                         for(int i = firstPageNumber; i <= lastPageNumber; i++)
1388                                         {
1389                                                 string argText = i.ToString(NumberFormatInfo.InvariantInfo);
1390                                                 if(i == currPage)
1391                                                 {
1392                                                         Label cPageLabel = new Label();
1393                                                         cPageLabel.Text = argText;
1394                                                         toAdd.Controls.Add(cPageLabel);
1395                                                 } else
1396                                                 {
1397                                                         LinkButton indexButton = new DataGridLinkButton();
1398                                                         indexButton.Text = argText;
1399                                                         indexButton.CommandName = "Page";
1400                                                         indexButton.CommandArgument = argText;
1401                                                         indexButton.CausesValidation = false;
1402                                                         toAdd.Controls.Add(indexButton);
1403                                                 }
1404                                                 if(i < lastPageNumber)
1405                                                         toAdd.Controls.Add(new LiteralControl("&nbsp;"));
1406                                         }
1407                                 }
1408                                 if(pageCount > lastPageNumber)
1409                                 {
1410                                         toAdd.Controls.Add(new LiteralControl("&nbsp;"));
1411                                         LinkButton contLink = new DataGridLinkButton();
1412                                         contLink.Text = "...";
1413                                         contLink.CommandName = "Page";
1414                                         contLink.CommandArgument = (lastPageNumber + 1).ToString(NumberFormatInfo.InvariantInfo);
1415                                         contLink.CausesValidation = false;
1416                                         toAdd.Controls.Add(contLink);
1417                                 }
1418                         }
1419                         item.Cells.Add(toAdd);
1420                 }
1421
1422                 private PagedDataSource CreatePagedDataSource()
1423                 {
1424                         PagedDataSource retVal;
1425
1426                         retVal = new PagedDataSource();
1427                         retVal.CurrentPageIndex = CurrentPageIndex;
1428                         retVal.PageSize         = PageSize;
1429                         retVal.AllowPaging      = AllowPaging;
1430                         retVal.AllowCustomPaging = AllowCustomPaging;
1431                         retVal.VirtualCount      = VirtualItemCount;
1432
1433                         return retVal;
1434                 }
1435
1436                 ///<summary>
1437                 /// UnDocumented method
1438                 /// </summary>
1439                 protected virtual ArrayList CreateColumnSet(PagedDataSource source, bool useDataSource)
1440                 {
1441                         DataGridColumn[] cols = new DataGridColumn [Columns.Count];
1442                         Columns.CopyTo (cols, 0);
1443                         ArrayList l_columns = new ArrayList ();
1444
1445                         foreach (DataGridColumn current in cols)
1446                                 l_columns.Add (current);
1447
1448                         if (AutoGenerateColumns) {
1449                                 ArrayList auto_columns = null;
1450                                 if (useDataSource) {
1451                                         auto_columns = AutoCreateColumns (source);
1452                                         autoGenColsArrayList = auto_columns;
1453                                 } else {
1454                                         auto_columns = autoGenColsArrayList;
1455                                 }
1456
1457                                 if (auto_columns != null && auto_columns.Count > 0)
1458                                         l_columns.AddRange (auto_columns);
1459                         }
1460
1461                         return l_columns;
1462                 }
1463
1464                 /// <summary>
1465                 /// Generates the columns when AutoGenerateColumns is true.
1466                 /// This method is called by CreateColumnSet when dataSource
1467                 /// is to be used and columns need to be generated automatically.
1468                 /// </summary>
1469                 private ArrayList AutoCreateColumns(PagedDataSource source)
1470                 {
1471                         if(source != null)
1472                         {
1473                                 ArrayList retVal = new ArrayList();
1474                                 PropertyDescriptorCollection props = source.GetItemProperties(new PropertyDescriptor[0]);
1475                                 Type      prop_type;
1476                                 BoundColumn b_col;
1477                                 if(props == null)
1478                                 {
1479                                         object fitem = null;
1480                                         prop_type   = null;
1481                                         PropertyInfo prop_item =  source.DataSource.GetType().GetProperty("Item",
1482                                                   BindingFlags.Instance | BindingFlags.Static |
1483                                                   BindingFlags.Public, null, null,
1484                                                   new Type[] { typeof(int) }, null);
1485                                         
1486                                         if(prop_item != null)
1487                                         {
1488                                                 prop_type = prop_item.PropertyType;
1489                                         }
1490                                         if(prop_type == null || prop_type == typeof(object))
1491                                         {
1492                                                 
1493                                                 IEnumerator en = source.GetEnumerator();
1494                                                 if(en.MoveNext())
1495                                                         fitem = en.Current;
1496                                                 if(fitem != null)
1497                                                 {
1498                                                         prop_type = fitem.GetType();
1499                                                 }
1500                                                 StoreEnumerator(en, fitem);
1501                                         }
1502                                         
1503                                         if(fitem != null && fitem is ICustomTypeDescriptor)
1504                                         {
1505                                                 props = TypeDescriptor.GetProperties(fitem);
1506                                         } else if(prop_type != null) {
1507                                                 if(IsBindableType(prop_type))
1508                                                 {
1509                                                         b_col = new BoundColumn();
1510                                                         ((IStateManager)b_col).TrackViewState();
1511                                                         b_col.HeaderText = "Item";
1512                                                         b_col.SortExpression = "Item";
1513                                                         b_col.DataField  = BoundColumn.thisExpr;
1514                                                         b_col.SetOwner(this);
1515                                                         retVal.Add(b_col);
1516                                                 } else
1517                                                 {
1518                                                         props = TypeDescriptor.GetProperties(prop_type);
1519                                                 }
1520                                         }
1521                                         
1522                                 }
1523                                 if(props != null && props.Count > 0)
1524                                 {
1525                                         //IEnumerable p_en = props.GetEnumerator();
1526                                         try
1527                                         {
1528                                                 foreach(PropertyDescriptor current in props)
1529                                                 {
1530                                                         if(IsBindableType(current.PropertyType))
1531                                                         {
1532                                                                 b_col = new BoundColumn();
1533                                                                 ((IStateManager)b_col).TrackViewState();
1534                                                                 b_col.HeaderText     = current.Name;
1535                                                                 b_col.SortExpression = current.Name;
1536                                                                 b_col.DataField      = current.Name;
1537                                                                 b_col.ReadOnly     = current.IsReadOnly;
1538                                                                 b_col.SetOwner(this);
1539                                                                 retVal.Add(b_col);
1540                                                         }
1541                                                 }
1542                                         } finally
1543                                         {
1544                                                 if(props is IDisposable)
1545                                                         ((IDisposable)props).Dispose();
1546                                         }
1547                                 }
1548                                 if(retVal.Count > 0)
1549                                 {
1550                                         return retVal;
1551                                 }
1552                                 throw new HttpException(HttpRuntime.FormatResourceString("DataGrid_NoAutoGenColumns", ID));
1553                         }
1554                         return null;
1555                 }
1556
1557                 internal void StoreEnumerator(IEnumerator source, object firstItem)
1558                 {
1559                         storedData      = source;
1560                         storedDataFirst = firstItem;
1561                         storedDataValid = true;
1562                 }
1563
1564                 internal void OnColumnsChanged()
1565                 {
1566                 }
1567
1568                 internal void OnPagerChanged()
1569                 {
1570                 }
1571         }
1572 }