2008-03-13 Marek Habersack <mhabersack@novell.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 //      Jackson Harper (jackson@ximian.com)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //
8 // (C) 2005 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System.Web.Util;
31 using System.Collections;
32 using System.Globalization;
33 using System.ComponentModel;
34 using System.Reflection;
35 using System.Security.Permissions;
36
37 namespace System.Web.UI.WebControls {
38
39         // CAS
40         [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
41         [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
42         // attributes
43         [Editor("System.Web.UI.Design.WebControls.DataGridComponentEditor, " + Consts.AssemblySystem_Design, typeof(System.ComponentModel.ComponentEditor))]
44         [Designer("System.Web.UI.Design.WebControls.DataGridDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
45         public class DataGrid : BaseDataList, INamingContainer {
46
47                 public const string CancelCommandName = "Cancel";
48                 public const string DeleteCommandName = "Delete";
49                 public const string EditCommandName = "Edit";
50                 public const string SelectCommandName = "Select";
51                 public const string SortCommandName = "Sort";
52                 public const string UpdateCommandName = "Update";
53
54                 public const string PageCommandName = "Page";
55                 public const string NextPageCommandArgument = "Next";
56                 public const string PrevPageCommandArgument = "Prev";
57
58                 private static readonly object CancelCommandEvent = new object ();
59                 private static readonly object DeleteCommandEvent = new object ();
60                 private static readonly object EditCommandEvent = new object ();
61                 private static readonly object ItemCommandEvent = new object ();
62                 private static readonly object ItemCreatedEvent = new object ();
63                 private static readonly object ItemDataBoundEvent = new object ();
64                 private static readonly object PageIndexChangedEvent = new object ();
65                 private static readonly object SortCommandEvent = new object ();
66                 private static readonly object UpdateCommandEvent = new object ();
67
68                 private TableItemStyle alt_item_style;
69                 private TableItemStyle edit_item_style;
70                 private TableItemStyle footer_style;
71                 private TableItemStyle header_style;
72                 private TableItemStyle item_style;
73                 private TableItemStyle selected_style;
74                 private DataGridPagerStyle pager_style;
75                 
76                 private ArrayList items_list;
77                 private DataGridItemCollection items;
78
79                 private ArrayList columns_list;
80                 private DataGridColumnCollection columns;
81
82                 private ArrayList data_source_columns_list;
83                 private DataGridColumnCollection data_source_columns;
84
85                 private Table render_table;
86                 private DataGridColumn [] render_columns;
87                 private PagedDataSource paged_data_source;
88                 private IEnumerator data_enumerator;
89                 
90                 [DefaultValue(false)]
91                 [WebSysDescription ("")]
92                 [WebCategory ("Paging")]
93                 public virtual bool AllowCustomPaging {
94                         get { return ViewState.GetBool ("AllowCustomPaging", false); }
95                         set { ViewState ["AllowCustomPaging"] = value; }
96                 }
97
98                 [DefaultValue(false)]
99                 [WebSysDescription ("")]
100                 [WebCategory ("Paging")]
101                 public virtual bool AllowPaging {
102                         get { return ViewState.GetBool ("AllowPaging", false); }
103                         set { ViewState ["AllowPaging"] = value; }
104                 }
105
106                 [DefaultValue(false)]
107                 [WebSysDescription ("")]
108                 [WebCategory ("Behavior")]
109                 public virtual bool AllowSorting {
110                         get { return ViewState.GetBool ("AllowSorting", false); }
111                         set { ViewState ["AllowSorting"] = value; }
112                 }
113
114                 [DefaultValue(true)]
115                 [WebSysDescription ("")]
116                 [WebCategory ("Behavior")]
117                 public virtual bool AutoGenerateColumns {
118                         get { return ViewState.GetBool ("AutoGenerateColumns", true); }
119                         set { ViewState ["AutoGenerateColumns"] = value; }
120                 }
121
122 #if NET_2_0
123                 [UrlProperty]
124 #else
125                 [Bindable(true)]
126 #endif
127                 [DefaultValue("")]
128                 [Editor("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
129                 [WebSysDescription ("")]
130                 [WebCategory ("Appearance")]
131                 public virtual string BackImageUrl {
132                         get { return TableStyle.BackImageUrl; }
133                         set { TableStyle.BackImageUrl = value; }
134                 }
135
136 #if ONLY_1_1
137                 [Bindable(true)]
138 #endif
139                 [Browsable(false)]
140                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
141                 [WebSysDescription ("")]
142                 [WebCategory ("Behavior")]
143                 public int CurrentPageIndex {
144                         get { return ViewState.GetInt ("CurrentPageIndex", 0); }
145                         set {
146                                 if (value < 0)
147                                         throw new ArgumentOutOfRangeException ("value");
148                                 ViewState ["CurrentPageIndex"] = value;
149                         }
150                 }
151
152                 [DefaultValue(-1)]
153                 [WebSysDescription ("")]
154                 [WebCategory ("Misc")]
155                 public virtual int EditItemIndex {
156                         get { return ViewState.GetInt ("EditItemIndex", -1); }
157                         set {
158                                 if (value < -1)
159                                         throw new ArgumentOutOfRangeException ("value");
160                                 ViewState ["EditItemIndex"] = value;
161                         }
162                 }
163
164                 [Browsable(false)]
165                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
166                 [WebSysDescription ("")]
167                 [WebCategory ("Style")]
168                 public int PageCount {
169                         get {
170                                 if (paged_data_source != null)
171                                         return paged_data_source.PageCount;
172
173                                 return ViewState.GetInt ("PageCount", 0);
174                         }
175                 }
176
177                 [DefaultValue(10)]
178                 [WebSysDescription ("")]
179                 [WebCategory ("Paging")]
180                 public virtual int PageSize {
181                         get { return ViewState.GetInt ("PageSize", 10); }
182                         set {
183                                 if (value < 1)
184                                         throw new ArgumentOutOfRangeException ("value");
185                                 ViewState ["PageSize"] = value;
186                         }
187                 }
188
189                 void AdjustItemTypes (int prev_select, int new_select)
190                 {
191                         if (items_list == null)
192                                 return; // nothing to select
193
194                         int count = items_list.Count;
195                         if (count == 0)
196                                 return; // nothing to select
197
198                         DataGridItem item;
199                         // Restore item type for the previously selected one.
200                         if (prev_select >= 0 && prev_select < count) {
201                                 item = (DataGridItem) items_list [prev_select];
202                                 
203                                 if (item.ItemType == ListItemType.EditItem) {
204                                         // nothing to do. This has priority.
205                                 } else if ((item.ItemIndex % 2) != 0) {
206                                         item.SetItemType (ListItemType.AlternatingItem);
207                                 } else {
208                                         item.SetItemType (ListItemType.Item);
209                                 }
210                         }
211
212                         if (new_select == -1 || new_select >= count)
213                                 return; // nothing to select
214
215                         item = (DataGridItem) items_list [new_select];
216                         if (item.ItemType != ListItemType.EditItem) // EditItem takes precedence
217                                 item.SetItemType (ListItemType.SelectedItem);
218                 }
219
220                 [Bindable(true)]
221                 [DefaultValue(-1)]
222                 [WebSysDescription ("")]
223                 [WebCategory ("Paging")]
224                 public virtual int SelectedIndex {
225                         get { return ViewState.GetInt ("SelectedIndex", -1); }
226                         set {
227                                 if (value < -1)
228                                         throw new ArgumentOutOfRangeException ("value");
229
230                                 int selected_index = ViewState.GetInt ("SelectedIndex", -1);
231                                 AdjustItemTypes (selected_index, value);
232                                 ViewState ["SelectedIndex"] = value;
233                         }
234                 }
235
236                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
237                 [NotifyParentProperty(true)]
238                 [PersistenceMode(PersistenceMode.InnerProperty)]
239                 [WebSysDescription ("")]
240                 [WebCategory ("Style")]
241                 public virtual TableItemStyle AlternatingItemStyle {
242                         get {
243                                 if (alt_item_style == null) {
244                                         alt_item_style = new TableItemStyle ();
245                                         if (IsTrackingViewState)
246                                                 alt_item_style.TrackViewState ();
247                                 }
248                                 return alt_item_style;
249                         }
250                 }
251
252                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
253                 [NotifyParentProperty(true)]
254                 [PersistenceMode(PersistenceMode.InnerProperty)]
255                 [WebSysDescription ("")]
256                 [WebCategory ("Style")]
257                 public virtual TableItemStyle EditItemStyle {
258                         get {
259                                 if (edit_item_style == null) {
260                                         edit_item_style = new TableItemStyle ();
261                                         if (IsTrackingViewState)
262                                                 edit_item_style.TrackViewState ();
263                                 }
264                                 return edit_item_style;
265                         }
266                 }
267
268                 [DefaultValue(null)]
269                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
270                 [NotifyParentProperty(true)]
271                 [PersistenceMode(PersistenceMode.InnerProperty)]
272                 [WebSysDescription ("")]
273                 [WebCategory ("Style")]
274                 public virtual TableItemStyle FooterStyle {
275                         get {
276                                 if (footer_style == null) {
277                                         footer_style = new TableItemStyle ();
278                                         if (IsTrackingViewState)
279                                                 footer_style.TrackViewState ();
280                                 }
281                                 return footer_style;
282                         }
283                 }
284
285                 [DefaultValue(null)]
286                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
287                 [NotifyParentProperty(true)]
288                 [PersistenceMode(PersistenceMode.InnerProperty)]
289                 [WebSysDescription ("")]
290                 [WebCategory ("Style")]
291                 public virtual TableItemStyle HeaderStyle {
292                         get {
293                                 if (header_style == null) {
294                                         header_style = new TableItemStyle ();
295                                         if (IsTrackingViewState)
296                                                 header_style.TrackViewState ();
297                                 }
298                                 return header_style;
299                         }
300                 }
301
302                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
303                 [NotifyParentProperty(true)]
304                 [PersistenceMode(PersistenceMode.InnerProperty)]
305                 [WebSysDescription ("")]
306                 [WebCategory ("Style")]
307                 public virtual TableItemStyle ItemStyle {
308                         get {
309                                 if (item_style == null) {
310                                         item_style = new TableItemStyle ();
311                                         if (IsTrackingViewState)
312                                                 item_style.TrackViewState ();
313                                 }
314                                 return item_style;
315                         }
316                 }
317
318                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
319                 [NotifyParentProperty(true)]
320                 [PersistenceMode(PersistenceMode.InnerProperty)]
321                 [WebSysDescription ("")]
322                 [WebCategory ("Style")]
323                 public virtual TableItemStyle SelectedItemStyle {
324                         get {
325                                 if (selected_style == null) {
326                                         selected_style = new TableItemStyle ();
327                                         if (IsTrackingViewState)
328                                                 selected_style.TrackViewState ();
329                                 }
330                                 return selected_style;
331                         }
332                 }
333
334                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
335                 [NotifyParentProperty(true)]
336                 [PersistenceMode(PersistenceMode.InnerProperty)]
337                 [WebSysDescription ("")]
338                 [WebCategory ("Style")]
339                 public virtual DataGridPagerStyle PagerStyle {
340                         get {
341                                 if (pager_style == null) {
342                                         pager_style = new DataGridPagerStyle ();
343                                         if (IsTrackingViewState)
344                                                 pager_style.TrackViewState ();
345                                 }
346                                 return pager_style;
347                         }
348                 }
349
350                 [Browsable(false)]
351                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
352                 [WebSysDescription ("")]
353                 [WebCategory ("Style")]
354                 public virtual DataGridItemCollection Items {
355                         get {
356                                 EnsureChildControls ();
357                                 if (items == null) {
358                                         if (items_list == null)
359                                                 items_list = new ArrayList ();
360                                         items = new DataGridItemCollection (items_list);
361                                 }
362                                 return items;
363                         }
364                 }
365
366                 [DefaultValue (null)]
367                 [Editor ("System.Web.UI.Design.WebControls.DataGridColumnCollectionEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
368                 [MergableProperty (false)]
369                 [PersistenceMode (PersistenceMode.InnerProperty)]
370                 [WebSysDescription ("")]
371                 [WebCategory ("Behavior")]
372                 public virtual DataGridColumnCollection Columns {
373                         get {
374                                 if (columns == null) {
375                                         columns_list = new ArrayList ();
376                                         columns = new DataGridColumnCollection (this, columns_list);
377                                         if (IsTrackingViewState) {
378                                                 IStateManager manager = (IStateManager) columns;
379                                                 manager.TrackViewState ();
380                                         }
381                                 }
382                                 return columns;
383                         }
384                 }
385
386                 private DataGridColumnCollection DataSourceColumns {
387                         get {
388                                 if (data_source_columns == null) {
389                                         data_source_columns_list = new ArrayList ();
390                                         data_source_columns = new DataGridColumnCollection (this,
391                                                         data_source_columns_list);
392                                         if (IsTrackingViewState) {
393                                                 IStateManager manager = (IStateManager) data_source_columns;
394                                                 manager.TrackViewState ();
395                                         }
396                                 }
397                                 return data_source_columns;
398                         }
399                 }
400
401                 class TableID : Table
402                 {
403                         Control parent;
404
405                         public TableID (Control parent)
406                         {
407                                 this.parent = parent;
408                         }
409
410                         protected override void AddAttributesToRender (HtmlTextWriter writer)
411                         {
412                                 base.AddAttributesToRender (writer);
413                                 if (ID == null)
414                                         writer.AddAttribute ("id", parent.ClientID);
415                         }
416                 }
417                 
418                 private Table RenderTable {
419                         get {
420                                 if (render_table == null) {
421 #if ONLY_1_1
422                                         render_table = new TableID (this);
423 #else
424                                         render_table = new ChildTable ();
425 #endif
426                                         render_table.AutoID = false;
427                                 }
428                                 return render_table;
429                         }
430                 }
431
432                 [Browsable(false)]
433                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
434                 [WebSysDescription ("")]
435                 [WebCategory ("Paging")]
436                 public virtual DataGridItem SelectedItem {
437                         get {
438                                 if (SelectedIndex == -1)
439                                         return null;
440                                 return Items [SelectedIndex];
441                         }
442                 }
443
444 #if ONLY_1_1
445                 [Bindable(true)]
446 #endif
447                 [DefaultValue(false)]
448                 [WebSysDescription ("")]
449                 [WebCategory ("Appearance")]
450                 public virtual bool ShowFooter {
451                         get { return ViewState.GetBool ("ShowFooter", false); }
452                         set { ViewState ["ShowFooter"] = value; }
453                 }
454
455 #if ONLY_1_1
456                 [Bindable(true)]
457 #endif
458                 [DefaultValue(true)]
459                 [WebSysDescription ("")]
460                 [WebCategory ("Appearance")]
461                 public virtual bool ShowHeader {
462                         get { return ViewState.GetBool ("ShowHeader", true); }
463                         set { ViewState ["ShowHeader"] = value; }
464                 }
465
466                 [Browsable(false)]
467                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
468                 [WebSysDescription ("")]
469                 [WebCategory ("Appearance")]
470                 public virtual int VirtualItemCount {
471                         get { return ViewState.GetInt ("VirtualItemCount", 0); }
472                         set {
473                                 if (value < 0)
474                                         throw new ArgumentOutOfRangeException ("value");
475                                 ViewState ["VirtualItemCount"] = value;
476                         }
477                 }
478
479 #if NET_2_0
480                 protected override HtmlTextWriterTag TagKey {
481                         get { return HtmlTextWriterTag.Table; }
482                 }
483 #endif
484
485                 private TableStyle TableStyle {
486                         get { return (TableStyle) ControlStyle; }
487                 }
488
489                 static Type [] item_args = new Type [] {typeof (int) };
490                 void AddColumnsFromSource (PagedDataSource data_source)
491                 {
492                         PropertyDescriptorCollection props = null;
493                         Type ptype = null;
494                         bool no_items = false;
495
496                         // Use plain reflection for the Item property.
497                         // If we use TypeDescriptor, props will hold
498                         // all of the Type properties, which will be listed as columns
499                         Type ds_type = data_source.GetType ();
500                         PropertyInfo pinfo = ds_type.GetProperty ("Item", item_args);
501                         if (pinfo == null) {
502                                 IEnumerator items = (data_source.DataSource != null) ? data_source.GetEnumerator () : null;
503                                 if (items != null && items.MoveNext ()) {
504                                         object data = items.Current;
505                                         if ((data is ICustomTypeDescriptor) || (!IsBindableType(data.GetType())))
506                                                 props = TypeDescriptor.GetProperties (data);
507                                         else if (data != null)
508                                                 ptype = data.GetType ();
509                                         data_enumerator = items;
510                                 } else {
511                                         no_items = true;
512                                 }
513                         } else {
514                                 ptype = pinfo.PropertyType;
515                         }
516
517                         if (ptype != null) {
518                                 // Found the "Item" property
519                                 AddPropertyToColumns ();
520                         } else if (props != null) {
521                                 foreach (PropertyDescriptor pd in props)
522                                         AddPropertyToColumns (pd, false);
523                         } else if (!no_items) {
524                                 // This is not thrown for an empty ArrayList.
525                                 string msg = String.Format ("DataGrid '{0}' cannot autogenerate " +
526                                                         "columns from the given datasource. {1}", ID, ptype);
527                                 throw new HttpException (msg);
528                         }
529                 }
530
531                 protected virtual ArrayList CreateColumnSet (PagedDataSource dataSource, bool useDataSource)
532                 {
533                         ArrayList res = new ArrayList ();
534                         if (columns_list != null)
535                                 res.AddRange (columns_list);
536
537                         if (AutoGenerateColumns) {
538                                 if (useDataSource) {
539                                         data_enumerator = null;
540                                         PropertyDescriptorCollection props = dataSource.GetItemProperties (null);
541                                         DataSourceColumns.Clear ();
542                                         if (props != null) {
543                                                 foreach (PropertyDescriptor d in props)
544                                                         AddPropertyToColumns (d, false);
545                                         } else {
546                                                 AddColumnsFromSource (dataSource);
547                                         }
548                                 }
549
550                                 if (data_source_columns != null && data_source_columns.Count > 0)
551                                         res.AddRange (data_source_columns);
552                         }
553
554                         return res;
555                 }
556
557                 private void AddPropertyToColumns ()
558                 {
559                         BoundColumn b = new BoundColumn ();
560                         if (IsTrackingViewState) {
561                                 IStateManager m = (IStateManager) b;
562                                 m.TrackViewState ();
563                         }
564                         b.Set_Owner (this);
565                         b.HeaderText = "Item";
566                         b.SortExpression = "Item";
567                         b.DataField  = BoundColumn.thisExpr;
568                         DataSourceColumns.Add (b);
569                 }
570
571                 private void AddPropertyToColumns (PropertyDescriptor prop, bool tothis)
572                 {
573                         BoundColumn b = new BoundColumn ();
574                         b.Set_Owner (this);
575                         if (IsTrackingViewState) {
576                                 IStateManager m = (IStateManager) b;
577                                 m.TrackViewState ();
578                         }
579                         b.HeaderText = prop.Name;
580                         b.DataField = (tothis ? BoundColumn.thisExpr : prop.Name);
581                         b.SortExpression = prop.Name;
582 #if NET_2_0
583                         if (string.Compare (DataKeyField, b.DataField, StringComparison.InvariantCultureIgnoreCase) == 0) {
584                                 b.ReadOnly = true;
585                         }
586 #endif
587                         DataSourceColumns.Add (b);
588                 }
589
590                 protected override void TrackViewState ()
591                 {
592                         base.TrackViewState ();
593
594                         if (pager_style != null)
595                                 pager_style.TrackViewState ();
596                         if (header_style != null)
597                                 header_style.TrackViewState ();
598                         if (footer_style != null)
599                                 footer_style.TrackViewState ();
600                         if (item_style != null)
601                                 item_style.TrackViewState ();
602                         if (alt_item_style != null)
603                                 alt_item_style.TrackViewState ();
604                         if (selected_style != null)
605                                 selected_style.TrackViewState ();
606                         if (edit_item_style != null)
607                                 edit_item_style.TrackViewState ();
608 #if NET_2_0
609                         if (ControlStyleCreated)
610                                 ControlStyle.TrackViewState ();
611 #endif
612                         IStateManager manager = (IStateManager) columns;
613                         if (manager != null)
614                                 manager.TrackViewState ();
615                 }
616
617                 protected override object SaveViewState ()
618                 {
619 #if NET_2_0
620                         object [] res = new object [11];
621 #else
622                         object [] res = new object [10];
623 #endif
624
625                         res [0] = base.SaveViewState ();
626                         if (columns != null) {
627                                 IStateManager cm = (IStateManager) columns;
628                                 res [1] = cm.SaveViewState ();
629                         }
630                         if (pager_style != null)
631                                 res [2] = pager_style.SaveViewState ();
632                         if (header_style != null)
633                                 res [3] = header_style.SaveViewState ();
634                         if (footer_style != null)
635                                 res [4] = footer_style.SaveViewState ();
636                         if (item_style != null)
637                                 res [5] = item_style.SaveViewState ();
638                         if (alt_item_style != null)
639                                 res [6] = alt_item_style.SaveViewState ();
640                         if (selected_style != null)
641                                 res [7] = selected_style.SaveViewState ();
642                         if (edit_item_style != null)
643                                 res [8] = edit_item_style.SaveViewState ();
644 #if NET_2_0
645                         if (ControlStyleCreated)
646                                 res [9] = ControlStyle.SaveViewState ();
647                         
648                         if (data_source_columns != null) {
649                                 IStateManager m = (IStateManager) data_source_columns;
650                                 res [10] = m.SaveViewState ();
651                         }
652 #else
653                         if (data_source_columns != null) {
654                                 IStateManager m = (IStateManager) data_source_columns;
655                                 res [9] = m.SaveViewState ();
656                         }
657 #endif
658
659                         return res;
660                 }
661
662                 protected override void LoadViewState (object savedState)
663                 {
664                         object [] pieces = savedState as object [];
665
666                         if (pieces == null)
667                                 return;
668
669                         base.LoadViewState (pieces [0]);
670                         if (columns != null) {
671                                 IStateManager cm = (IStateManager) columns;
672                                 cm.LoadViewState (pieces [1]);
673                         }
674                         if (pieces [2] != null)
675                                 PagerStyle.LoadViewState (pieces [2]);
676                         if (pieces [3] != null)
677                                 HeaderStyle.LoadViewState (pieces [3]);
678                         if (pieces [4] != null)
679                                 FooterStyle.LoadViewState (pieces [4]);
680                         if (pieces [5] != null)
681                                 ItemStyle.LoadViewState (pieces [5]);
682                         if (pieces [6] != null)
683                                 AlternatingItemStyle.LoadViewState (pieces [6]);
684                         if (pieces [7] != null)
685                                 SelectedItemStyle.LoadViewState (pieces [7]);
686                         if (pieces [8] != null)
687                                 EditItemStyle.LoadViewState (pieces [8]);
688
689 #if NET_2_0
690                         if (pieces [9] != null)
691                                 ControlStyle.LoadViewState (pieces [8]);
692
693                         if (pieces [10] != null) {
694                                 // IStateManager manager = (IStateManager) DataSourceColumns;
695                                 // manager.LoadViewState (pieces [10]);
696                                 object [] cols = (object []) pieces [10];
697                                 foreach (object o in cols) {
698                                         BoundColumn c = new BoundColumn ();
699                                         ((IStateManager) c).TrackViewState ();
700                                         c.Set_Owner (this);
701                                         ((IStateManager) c).LoadViewState (o);
702                                         DataSourceColumns.Add (c);
703                                 }
704                         }
705 #else
706                         if (pieces [9] != null) {
707                                 // IStateManager manager = (IStateManager) DataSourceColumns;
708                                 // manager.LoadViewState (pieces [9]);
709                                 object [] cols = (object []) pieces [9];
710                                 foreach (object o in cols) {
711                                         BoundColumn c = new BoundColumn ();
712                                         c.Set_Owner (this);
713                                         ((IStateManager) c).LoadViewState (o);
714                                         DataSourceColumns.Add (c);
715                                 }
716                         }
717 #endif
718                 }
719
720                 protected override Style CreateControlStyle ()
721                 {
722 #if NET_2_0
723                         TableStyle res = new TableStyle ();
724 #else
725                         TableStyle res = new TableStyle (ViewState);
726 #endif
727                         res.GridLines = GridLines.Both;
728                         res.CellSpacing = 0;
729                         return res;
730                 }
731
732                 protected virtual void InitializeItem (DataGridItem item, DataGridColumn [] columns)
733                 {
734                         bool th = UseAccessibleHeader && item.ItemType == ListItemType.Header;
735                         for (int i = 0; i < columns.Length; i++) {
736                                 TableCell cell = null;
737                                 if (th) {
738                                         cell = new TableHeaderCell ();
739                                         cell.Attributes["scope"] = "col";
740                                 }
741                                 else
742                                         cell = new TableCell ();
743                                 columns [i].InitializeCell (cell, i, item.ItemType);
744                                 item.Cells.Add (cell);
745                         }
746                 }
747
748                 protected virtual void InitializePager (DataGridItem item, int columnSpan, PagedDataSource pagedDataSource)
749                 {
750                         TableCell pager_cell;
751                         if (PagerStyle.Mode == PagerMode.NextPrev)
752                                 pager_cell = InitializeNextPrevPager (item, columnSpan, pagedDataSource);
753                         else
754                                 pager_cell = InitializeNumericPager (item, columnSpan, pagedDataSource);
755
756                         item.Controls.Add (pager_cell);
757                 }
758
759                 private TableCell InitializeNumericPager (DataGridItem item, int columnSpan,
760                                 PagedDataSource paged)
761                 {
762                         TableCell res = new TableCell ();
763                         res.ColumnSpan = columnSpan;
764
765                         int button_count = PagerStyle.PageButtonCount;
766                         int current = paged.CurrentPageIndex;
767                         int start = current - (current % button_count);
768                         int end = start + button_count;
769
770                         if (end > paged.PageCount)
771                                 end = paged.PageCount;
772
773                         if (start > 0) {
774                                 LinkButton link = new LinkButton ();
775                                 link.Text = "...";
776                                 link.CommandName = PageCommandName;
777                                 link.CommandArgument = start.ToString (CultureInfo.InvariantCulture);
778                                 link.CausesValidation = false;
779                                 res.Controls.Add (link);
780                                 res.Controls.Add (new LiteralControl ("&nbsp;"));
781                         }
782
783                         for (int i = start; i < end; i++) {
784                                 Control number = null;
785                                 string page = (i + 1).ToString (CultureInfo.InvariantCulture);
786                                 if (i != paged.CurrentPageIndex) {
787                                         LinkButton link = new LinkButton ();
788                                         link.Text = page;
789                                         link.CommandName = PageCommandName;
790                                         link.CommandArgument = page;
791                                         link.CausesValidation = false;
792                                         number = link;
793                                 } else {
794                                         Label pageLabel = new Label();
795                                         pageLabel.Text = page;
796                                         number = pageLabel;
797                                 }
798
799                                 res.Controls.Add (number);
800                                 if (i < end - 1)
801                                         res.Controls.Add (new LiteralControl ("&nbsp;"));
802                         }
803
804                         if (end < paged.PageCount) {
805                                 res.Controls.Add (new LiteralControl ("&nbsp;"));
806                                 LinkButton link = new LinkButton ();
807                                 link.Text = "...";
808                                 link.CommandName = PageCommandName;
809                                 link.CommandArgument = (end + 1).ToString (CultureInfo.InvariantCulture);
810                                 link.CausesValidation = false;
811                                 res.Controls.Add (link);
812                         }
813
814                         return res;
815                 }
816
817                 private TableCell InitializeNextPrevPager (DataGridItem item, int columnSpan, PagedDataSource paged)
818                 {
819                         TableCell res = new TableCell ();
820                         res.ColumnSpan = columnSpan;
821
822                         Control prev;
823                         Control next;
824
825                         if (paged.IsFirstPage) {
826                                 Label l = new Label ();
827                                 l.Text = PagerStyle.PrevPageText;
828                                 prev = l;
829                         } else {
830 #if NET_2_0
831                                 LinkButton l = new DataControlLinkButton ();
832 #else
833                                 LinkButton l = new LinkButton ();
834 #endif
835                                 l.Text = PagerStyle.PrevPageText;
836                                 l.CommandName = PageCommandName;
837                                 l.CommandArgument = PrevPageCommandArgument;
838                                 l.CausesValidation = false;
839                                 prev = l;
840                         }
841
842                         if (paged.Count > 0 && !paged.IsLastPage) {
843 #if NET_2_0
844                                 LinkButton l = new DataControlLinkButton ();
845 #else
846                                 LinkButton l = new LinkButton ();
847 #endif
848                                 l.Text = PagerStyle.NextPageText;
849                                 l.CommandName = PageCommandName;
850                                 l.CommandArgument = NextPageCommandArgument;
851                                 l.CausesValidation = false;
852                                 next = l;
853                         } else {
854                                 Label l = new Label ();
855                                 l.Text = PagerStyle.NextPageText;
856                                 next = l;
857                         }
858
859                         res.Controls.Add (prev);
860                         res.Controls.Add (new LiteralControl ("&nbsp;"));
861                         res.Controls.Add (next);
862
863                         return res;
864                 }
865                                 
866                 protected virtual DataGridItem CreateItem (int itemIndex, int dataSourceIndex,
867                                 ListItemType itemType)
868                 {
869                         DataGridItem res = new DataGridItem (itemIndex, dataSourceIndex, itemType);
870                         return res;
871                 }
872
873                 private DataGridItem CreateItem (int item_index, int data_source_index,
874                                 ListItemType type, bool data_bind, object data_item,
875                                 PagedDataSource paged)
876                 {
877                         DataGridItem res = CreateItem (item_index, data_source_index, type);
878                         DataGridItemEventArgs args = new DataGridItemEventArgs (res);
879                         bool no_pager = (type != ListItemType.Pager);
880
881                         if (no_pager) {
882                                 InitializeItem (res, render_columns);
883                                 if (data_bind)
884                                         res.DataItem = data_item;
885                                 OnItemCreated (args);
886                         } else {
887                                 InitializePager (res, render_columns.Length, paged);
888                                 if (pager_style != null)
889                                         res.ApplyStyle (pager_style);
890                                 OnItemCreated (args);
891                         }
892
893                         // Add before the column is bound, so that the
894                         // value is saved in the viewstate
895                         RenderTable.Controls.Add (res);
896
897                         if (no_pager && data_bind) {
898                                 res.DataBind ();
899                                 OnItemDataBound (args);
900                                 res.DataItem = null;
901                         }
902                         return res;
903                 }
904
905                 class NCollection : ICollection {
906                         int n;
907
908                         public NCollection (int n)
909                         {
910                                 this.n = n;
911                         }
912
913                         public IEnumerator GetEnumerator ()
914                         {
915                                 for (int i = 0; i < n; i++)
916                                         yield return i;
917                         }
918
919                         public int Count {
920                                 get { return n; }
921                         }
922
923                         public bool IsSynchronized {
924                                 get { return false; }
925                         }
926
927                         public object SyncRoot {
928                                 get { return this; }
929                         }
930
931                         public void CopyTo (Array array, int index)
932                         {
933                                 throw new NotImplementedException ("This should never be called");
934                         }
935                 }
936
937                 protected override void CreateControlHierarchy (bool useDataSource)
938                 {
939                         Controls.Clear ();
940                         RenderTable.Controls.Clear ();
941                         Controls.Add (RenderTable);
942                         
943                         IEnumerable data_source;
944                         ArrayList keys = null;
945                         if (useDataSource) {
946 #if NET_2_0
947                                 if (IsBoundUsingDataSourceID)
948                                         data_source = GetData ();
949                                 else
950 #endif
951                                 data_source = DataSourceResolver.ResolveDataSource (DataSource, DataMember);
952                                 if (data_source == null) {
953                                         Controls.Clear ();
954                                         return;
955                                 }
956                                 
957                                 keys = DataKeysArray;
958                                 keys.Clear ();
959                         } else {
960                                 int nitems = ViewState.GetInt ("Items", 0);
961                                 data_source = new NCollection (nitems);
962                         }
963
964                         paged_data_source = new PagedDataSource ();
965                         PagedDataSource pds = paged_data_source;
966                         pds.AllowPaging = AllowPaging;
967                         pds.AllowCustomPaging = AllowCustomPaging;
968                         pds.DataSource = data_source;
969                         pds.CurrentPageIndex = CurrentPageIndex;
970                         pds.PageSize = PageSize;
971                         pds.VirtualCount = VirtualItemCount;
972
973                         if ((pds.IsPagingEnabled) && (pds.PageCount < pds.CurrentPageIndex)) {
974                                 Controls.Clear ();
975                                 throw new HttpException ("Invalid DataGrid PageIndex");
976                         }
977                         
978                         ArrayList cList = CreateColumnSet (paged_data_source, useDataSource);
979                         if (cList.Count == 0) {
980                                 Controls.Clear ();
981                                 return;
982                         }
983                         
984                         Page page = this.Page;
985                         if (page != null)
986                                 page.RequiresPostBackScript ();
987                         
988                         render_columns = new DataGridColumn [cList.Count];
989                         for (int c = 0; c < cList.Count; c++) {
990                                 DataGridColumn col = (DataGridColumn) cList [c];
991                                 col.Set_Owner (this);
992                                 col.Initialize ();
993                                 render_columns [c] = col;
994                         }
995
996                         if (pds.IsPagingEnabled)
997                                 CreateItem (-1, -1, ListItemType.Pager, false, null, pds);
998
999                         CreateItem (-1, -1, ListItemType.Header, useDataSource, null, pds);
1000
1001                         // No indexer on PagedDataSource so we have to do
1002                         // this silly foreach and index++
1003                         if (items_list == null)
1004                                 items_list = new ArrayList ();
1005                         else
1006                                 items_list.Clear();
1007
1008                         bool skip_first = false;
1009                         IEnumerator enumerator = null;
1010                         if (data_enumerator != null) {
1011                                 // replaced when creating bound columns
1012                                 enumerator = data_enumerator;
1013                                 skip_first = true;
1014                         } else if (pds.DataSource != null) {
1015                                 enumerator = pds.GetEnumerator ();
1016                         } else {
1017                                 enumerator = null;
1018                         }
1019
1020                         int index = 0;
1021                         bool first = true;
1022                         string key = null;
1023                         int dataset_index = pds.FirstIndexInPage;
1024                         int selected_index = SelectedIndex;
1025                         int edit_item_index = EditItemIndex;
1026                         while (enumerator != null && (skip_first || enumerator.MoveNext ())) {
1027                                 // MS does not render <table blah></table> on empty datasource.
1028                                 if (first) {
1029                                         first = false;
1030                                         key = DataKeyField;
1031                                         skip_first = false;
1032                                 }
1033                                 object data = enumerator.Current;
1034                                 // This will throw if the DataKeyField is not there. As on MS, this
1035                                 // will not be hit on an empty datasource.
1036                                 // The values stored here can be used in events so that you can
1037                                 // get, for example, the row that was clicked
1038                                 // (data.Rows.Find (ItemsGrid.DataKeys [e.Item.ItemIndex]))
1039                                 // BaseDataList will keep the array across postbacks.
1040                                 if (useDataSource && key != "")
1041                                         keys.Add (DataBinder.GetPropertyValue (data, key));
1042
1043                                 ListItemType type = ListItemType.Item;
1044                                 if (index == edit_item_index) 
1045                                         type = ListItemType.EditItem;
1046                                 else if (index == selected_index) 
1047                                         type = ListItemType.SelectedItem;
1048                                 else if (index % 2 != 0) 
1049                                         type = ListItemType.AlternatingItem;
1050
1051                                 items_list.Add (CreateItem (index, dataset_index, type, useDataSource, data, pds));
1052                                 index++;
1053                                 dataset_index++;
1054                         }
1055
1056                         CreateItem (-1, -1, ListItemType.Footer, useDataSource, null, paged_data_source);
1057                         if (pds.IsPagingEnabled) {
1058                                 CreateItem (-1, -1, ListItemType.Pager, false, null, paged_data_source);
1059                                 if (useDataSource)
1060                                         ViewState ["Items"] = pds.IsCustomPagingEnabled ? index : pds.DataSourceCount;
1061                         } else if (useDataSource) {
1062                                 ViewState ["Items"] = index;
1063                         }
1064                 }
1065
1066                 void ApplyColumnStyle (TableCellCollection cells, ListItemType type)
1067                 {
1068                         int ncells = Math.Min (cells.Count, render_columns.Length);
1069                         if (ncells <= 0)
1070                                 return;
1071
1072                         for (int i = 0; i < ncells; i++) {
1073                                 Style style = null;
1074                                 TableCell cell = cells [i];
1075                                 DataGridColumn column = render_columns [i];
1076                                 if (!column.Visible) {
1077                                         cell.Visible = false;
1078                                         continue;
1079                                 }
1080
1081                                 style = column.GetStyle (type);
1082                                 if (style != null)
1083                                         cell.MergeStyle (style);
1084                         }
1085                 }
1086
1087                 protected override void PrepareControlHierarchy ()
1088                 {
1089                         if (!HasControls () || Controls.Count == 0)
1090                                 return; // No one called CreateControlHierarchy() with DataSource != null
1091
1092                         Table rt = render_table;
1093                         rt.CopyBaseAttributes (this);
1094                         rt.ApplyStyle (ControlStyle);
1095
1096                         rt.Caption = Caption;
1097                         rt.CaptionAlign = CaptionAlign;
1098                         rt.Enabled = Enabled;
1099
1100                         bool top_pager = true;
1101                         foreach (DataGridItem item in rt.Rows) {
1102                                 
1103                                 switch (item.ItemType) {
1104                                 case ListItemType.Item:
1105                                         ApplyItemStyle (item);
1106                                         break;
1107                                 case ListItemType.AlternatingItem:
1108                                         ApplyItemStyle (item);
1109                                         break;
1110                                 case ListItemType.EditItem:
1111                                         item.MergeStyle (edit_item_style);
1112                                         ApplyItemStyle (item);
1113                                         ApplyColumnStyle (item.Cells, ListItemType.EditItem);
1114                                         break;
1115                                 case ListItemType.Footer:
1116                                         if (!ShowFooter) {
1117                                                 item.Visible = false;
1118                                                 break;
1119                                         }
1120                                         if (footer_style != null)
1121                                                 item.MergeStyle (footer_style);
1122                                         ApplyColumnStyle (item.Cells, ListItemType.Footer);
1123                                         break;
1124                                 case ListItemType.Header:
1125                                         if (!ShowHeader) {
1126                                                 item.Visible = false;
1127                                                 break;
1128                                         }
1129                                         if (header_style != null)
1130                                                 item.MergeStyle (header_style);
1131                                         ApplyColumnStyle (item.Cells, ListItemType.Header);
1132                                         break;
1133                                 case ListItemType.SelectedItem:
1134                                         item.MergeStyle (selected_style);
1135                                         ApplyItemStyle (item);
1136                                         ApplyColumnStyle (item.Cells, ListItemType.SelectedItem);
1137                                         break;
1138                                 case ListItemType.Separator:
1139                                         ApplyColumnStyle (item.Cells, ListItemType.Separator);
1140                                         break;
1141                                 case ListItemType.Pager:
1142                                         DataGridPagerStyle ps = PagerStyle;
1143                                         if (ps.Visible == false || !paged_data_source.IsPagingEnabled) {
1144                                                 item.Visible = false;
1145                                         } else {
1146                                                 if (top_pager)
1147                                                         item.Visible = (ps.Position != PagerPosition.Bottom);
1148                                                 else
1149                                                         item.Visible = (ps.Position != PagerPosition.Top);
1150                                                 top_pager = false;
1151                                         }
1152
1153                                         if (item.Visible)
1154                                                 item.MergeStyle (pager_style);
1155                                         break;
1156                                 }
1157                         }
1158                 }
1159
1160                 void ApplyItemStyle (DataGridItem item)
1161                 {
1162                         if (item.ItemIndex % 2 != 0)
1163                                 item.MergeStyle (alt_item_style);
1164
1165                         item.MergeStyle (item_style);
1166                         ApplyColumnStyle (item.Cells, ListItemType.Item);
1167                 }
1168
1169                 protected override bool OnBubbleEvent (object source, EventArgs e)
1170                 {
1171                         DataGridCommandEventArgs de = e as DataGridCommandEventArgs;
1172
1173                         if (de == null)
1174                                 return false;
1175
1176                         string cn = de.CommandName;
1177                         CultureInfo inv = CultureInfo.InvariantCulture;
1178
1179                         OnItemCommand (de);
1180                         if (String.Compare (cn, CancelCommandName, true, inv) == 0) {
1181                                 OnCancelCommand (de);
1182                         } else if (String.Compare (cn, DeleteCommandName, true, inv) == 0) {
1183                                 OnDeleteCommand (de);
1184                         } else if (String.Compare (cn, EditCommandName, true, inv) == 0) {
1185                                 OnEditCommand (de);
1186                         } else if (String.Compare (cn, SelectCommandName, true, inv) == 0) {
1187                                 SelectedIndex = de.Item.ItemIndex;
1188                                 OnSelectedIndexChanged (de);
1189                         } else if (String.Compare (cn, SortCommandName, true, inv) == 0) {
1190                                 DataGridSortCommandEventArgs se = new DataGridSortCommandEventArgs (de.CommandSource, de);
1191                                 OnSortCommand (se);
1192                         } else if (String.Compare (cn, UpdateCommandName, true, inv) == 0) {
1193                                 OnUpdateCommand (de);
1194                         } else if (String.Compare (cn, PageCommandName, true, inv) == 0) {
1195                                 int new_index;
1196                                 if (String.Compare ((string) de.CommandArgument,
1197                                                     NextPageCommandArgument, true, inv) == 0) {
1198                                         new_index = CurrentPageIndex + 1;
1199                                 } else if (String.Compare ((string) de.CommandArgument,
1200                                                            PrevPageCommandArgument, true, inv) == 0) {
1201                                         new_index = CurrentPageIndex - 1;
1202                                 } else {
1203                                         // It seems to just assume it's an int and parses, no
1204                                         // checks to make sure its valid or anything.
1205                                         //  also it's always one less then specified, not sure
1206                                         // why that is.
1207                                         new_index = Int32.Parse ((string) de.CommandArgument, inv) - 1;
1208                                 }
1209                                 DataGridPageChangedEventArgs pc = new DataGridPageChangedEventArgs (
1210                                         de.CommandSource, new_index);
1211                                 OnPageIndexChanged (pc);
1212                         }
1213
1214                         return true;
1215                 }
1216
1217                 protected virtual void OnCancelCommand (DataGridCommandEventArgs e)
1218                 {
1219                         DataGridCommandEventHandler handler = (DataGridCommandEventHandler) Events [CancelCommandEvent];
1220                         if (handler != null)
1221                                 handler (this, e);
1222                 }
1223
1224                 protected virtual void OnDeleteCommand (DataGridCommandEventArgs e)
1225                 {
1226                         DataGridCommandEventHandler handler = (DataGridCommandEventHandler) Events [DeleteCommandEvent];
1227                         if (handler != null)
1228                                 handler (this, e);
1229                 }
1230
1231                 protected virtual void OnEditCommand (DataGridCommandEventArgs e)
1232                 {
1233                         DataGridCommandEventHandler handler = (DataGridCommandEventHandler) Events [EditCommandEvent];
1234                         if (handler != null)
1235                                 handler (this, e);
1236                 }
1237
1238                 protected virtual void OnItemCommand (DataGridCommandEventArgs e)
1239                 {
1240                         DataGridCommandEventHandler handler = (DataGridCommandEventHandler) Events [ItemCommandEvent];
1241                         if (handler != null)
1242                                 handler (this, e);
1243                 }
1244
1245                 protected virtual void OnItemCreated (DataGridItemEventArgs e)
1246                 {
1247                         DataGridItemEventHandler handler = (DataGridItemEventHandler) Events [ItemCreatedEvent];
1248                         if (handler != null)
1249                                 handler (this, e);
1250                 }
1251
1252                 protected virtual void OnItemDataBound (DataGridItemEventArgs e)
1253                 {
1254                         DataGridItemEventHandler handler = (DataGridItemEventHandler) Events [ItemDataBoundEvent];
1255                         if (handler != null)
1256                                 handler (this, e);
1257                 }
1258
1259                 protected virtual void OnPageIndexChanged (DataGridPageChangedEventArgs e)
1260                 {
1261                         DataGridPageChangedEventHandler handler = (DataGridPageChangedEventHandler) Events [PageIndexChangedEvent];
1262                         if (handler != null)
1263                                 handler (this, e);
1264                 }
1265
1266                 protected virtual void OnSortCommand (DataGridSortCommandEventArgs e)
1267                 {
1268                         DataGridSortCommandEventHandler handler = (DataGridSortCommandEventHandler) Events [SortCommandEvent];
1269                         if (handler != null)
1270                                 handler (this, e);
1271                 }
1272
1273                 protected virtual void OnUpdateCommand (DataGridCommandEventArgs e)
1274                 {
1275                         DataGridCommandEventHandler handler = (DataGridCommandEventHandler) Events [UpdateCommandEvent];
1276                         if (handler != null)
1277                                 handler (this, e);
1278                 }
1279
1280                 [WebSysDescription ("")]
1281                 [WebCategory ("Action")]
1282                 public event DataGridCommandEventHandler CancelCommand {
1283                         add { Events.AddHandler (CancelCommandEvent, value); }
1284                         remove { Events.RemoveHandler (CancelCommandEvent, value); }
1285                 }
1286
1287                 [WebSysDescription ("")]
1288                 [WebCategory ("Action")]
1289                 public event DataGridCommandEventHandler DeleteCommand {
1290                         add { Events.AddHandler (DeleteCommandEvent, value); }
1291                         remove { Events.RemoveHandler (DeleteCommandEvent, value); }
1292                 }
1293
1294                 [WebSysDescription ("")]
1295                 [WebCategory ("Action")]
1296                 public event DataGridCommandEventHandler EditCommand {
1297                         add { Events.AddHandler (EditCommandEvent, value); }
1298                         remove { Events.RemoveHandler (EditCommandEvent, value); }
1299                 }
1300
1301                 [WebSysDescription ("")]
1302                 [WebCategory ("Action")]
1303                 public event DataGridCommandEventHandler ItemCommand {
1304                         add { Events.AddHandler (ItemCommandEvent, value); }
1305                         remove { Events.RemoveHandler (ItemCommandEvent, value); }
1306                         
1307                 }
1308
1309                 [WebSysDescription ("")]
1310                 [WebCategory ("Action")]
1311                 public event DataGridItemEventHandler ItemCreated {
1312                         add { Events.AddHandler (ItemCreatedEvent, value); }
1313                         remove { Events.RemoveHandler (ItemCreatedEvent, value); }
1314                 }
1315
1316                 [WebSysDescription ("")]
1317                 [WebCategory ("Action")]
1318                 public event DataGridItemEventHandler ItemDataBound {
1319                         add { Events.AddHandler (ItemDataBoundEvent, value); }
1320                         remove { Events.RemoveHandler (ItemDataBoundEvent, value); }
1321                 }
1322
1323                 [WebSysDescription ("")]
1324                 [WebCategory ("Action")]
1325                 public event DataGridPageChangedEventHandler PageIndexChanged {
1326                         add { Events.AddHandler (PageIndexChangedEvent, value); }
1327                         remove { Events.RemoveHandler (PageIndexChangedEvent, value); }
1328                 }
1329
1330                 [WebSysDescription ("")]
1331                 [WebCategory ("Action")]
1332                 public event DataGridSortCommandEventHandler SortCommand {
1333                         add { Events.AddHandler (SortCommandEvent, value); }
1334                         remove { Events.RemoveHandler (SortCommandEvent, value); }
1335                 }
1336
1337                 [WebSysDescription ("")]
1338                 [WebCategory ("Action")]
1339                 public event DataGridCommandEventHandler UpdateCommand {
1340                         add { Events.AddHandler (UpdateCommandEvent, value); }
1341                         remove { Events.AddHandler (UpdateCommandEvent, value); }
1342                 }
1343         }
1344 }
1345
1346