Merge pull request #1840 from ludovic-henry/iolayer-thread-interrupt
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / GridView.cs
1 //
2 // System.Web.UI.WebControls.GridView.cs
3 //
4 // Authors:
5 //      Lluis Sanchez Gual (lluis@novell.com)
6 //
7 // Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Collections;
31 using System.Collections.Generic;
32 using System.Collections.Specialized;
33 using System.ComponentModel;
34 using System.Web.UI;
35 using System.Security.Permissions;
36 using System.Text;
37 using System.IO;
38 using System.Reflection;
39
40 namespace System.Web.UI.WebControls
41 {
42         [SupportsEventValidation]
43         [DesignerAttribute ("System.Web.UI.Design.WebControls.GridViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
44         [ControlValuePropertyAttribute ("SelectedValue")]
45         [DefaultEventAttribute ("SelectedIndexChanged")]
46         [DataKeyProperty ("DataKey")]
47         [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
48         [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
49         public class GridView: CompositeDataBoundControl, ICallbackEventHandler, ICallbackContainer, IPostBackEventHandler, IPostBackContainer, IPersistedSelector
50                 , IDataKeysControl, IDataBoundListControl, IDataBoundControl, IFieldControl
51         {
52                 Table table;
53                 GridViewRowCollection rows;
54                 GridViewRow bottomPagerRow;
55                 GridViewRow topPagerRow;
56                 
57                 IOrderedDictionary currentEditRowKeys;
58                 IOrderedDictionary currentEditNewValues;
59                 IOrderedDictionary currentEditOldValues;
60                 
61                 ITemplate pagerTemplate;
62                 ITemplate emptyDataTemplate;
63                 
64                 PropertyDescriptor[] cachedKeyProperties;
65                 PropertyDescriptor[] cachedSuffixKeyProperties;
66                 // View state
67                 DataControlFieldCollection columns;
68                 PagerSettings pagerSettings;
69                 
70                 TableItemStyle alternatingRowStyle;
71                 TableItemStyle editRowStyle;
72                 TableItemStyle emptyDataRowStyle;
73                 TableItemStyle footerStyle;
74                 TableItemStyle headerStyle;
75                 TableItemStyle pagerStyle;
76                 TableItemStyle rowStyle;
77                 TableItemStyle selectedRowStyle;
78                 TableItemStyle sortedAscendingCellStyle;
79                 TableItemStyle sortedAscendingHeaderStyle;
80                 TableItemStyle sortedDescendingCellStyle;
81                 TableItemStyle sortedDescendingHeaderStyle;
82
83                 List <DataKey> _dataKeySuffixList;
84                 DataKeyArray rowSuffixKeys;
85                 List <DataKey> _dataKeyList;
86                 DataKeyArray keys;
87                 DataKey oldEditValues;
88                 AutoGeneratedFieldProperties[] autoFieldProperties;
89                 string [] dataKeyNames = null;
90                 readonly string[] emptyKeys = new string[0];
91                 IEnumerator _dataEnumerator;
92                 
93                 static readonly object PageIndexChangedEvent = new object();
94                 static readonly object PageIndexChangingEvent = new object();
95                 static readonly object RowCancelingEditEvent = new object();
96                 static readonly object RowCommandEvent = new object();
97                 static readonly object RowCreatedEvent = new object();
98                 static readonly object RowDataBoundEvent = new object();
99                 static readonly object RowDeletedEvent = new object();
100                 static readonly object RowDeletingEvent = new object();
101                 static readonly object RowEditingEvent = new object();
102                 static readonly object RowUpdatedEvent = new object();
103                 static readonly object RowUpdatingEvent = new object();
104                 static readonly object SelectedIndexChangedEvent = new object();
105                 static readonly object SelectedIndexChangingEvent = new object();
106                 static readonly object SortedEvent = new object();
107                 static readonly object SortingEvent = new object();
108                 
109                 // Control state
110                 int pageIndex;
111                 int selectedIndex = -1;
112                 int editIndex = -1;
113                 int pageCount = 0;
114                 SortDirection sortDirection = SortDirection.Ascending;
115                 string sortExpression;
116                 
117                 public GridView ()
118                 {
119                         EnableModelValidation = true;
120                 }
121                 
122                 public event EventHandler PageIndexChanged {
123                         add { Events.AddHandler (PageIndexChangedEvent, value); }
124                         remove { Events.RemoveHandler (PageIndexChangedEvent, value); }
125                 }
126                 
127                 public event GridViewPageEventHandler PageIndexChanging {
128                         add { Events.AddHandler (PageIndexChangingEvent, value); }
129                         remove { Events.RemoveHandler (PageIndexChangingEvent, value); }
130                 }
131                 
132                 public event GridViewCancelEditEventHandler RowCancelingEdit {
133                         add { Events.AddHandler (RowCancelingEditEvent, value); }
134                         remove { Events.RemoveHandler (RowCancelingEditEvent, value); }
135                 }
136                 
137                 public event GridViewCommandEventHandler RowCommand {
138                         add { Events.AddHandler (RowCommandEvent, value); }
139                         remove { Events.RemoveHandler (RowCommandEvent, value); }
140                 }
141                 
142                 public event GridViewRowEventHandler RowCreated {
143                         add { Events.AddHandler (RowCreatedEvent, value); }
144                         remove { Events.RemoveHandler (RowCreatedEvent, value); }
145                 }
146                 
147                 public event GridViewRowEventHandler RowDataBound {
148                         add { Events.AddHandler (RowDataBoundEvent, value); }
149                         remove { Events.RemoveHandler (RowDataBoundEvent, value); }
150                 }
151                 
152                 public event GridViewDeletedEventHandler RowDeleted {
153                         add { Events.AddHandler (RowDeletedEvent, value); }
154                         remove { Events.RemoveHandler (RowDeletedEvent, value); }
155                 }
156                 
157                 public event GridViewDeleteEventHandler RowDeleting {
158                         add { Events.AddHandler (RowDeletingEvent, value); }
159                         remove { Events.RemoveHandler (RowDeletingEvent, value); }
160                 }
161                 
162                 public event GridViewEditEventHandler RowEditing {
163                         add { Events.AddHandler (RowEditingEvent, value); }
164                         remove { Events.RemoveHandler (RowEditingEvent, value); }
165                 }
166                 
167                 public event GridViewUpdatedEventHandler RowUpdated {
168                         add { Events.AddHandler (RowUpdatedEvent, value); }
169                         remove { Events.RemoveHandler (RowUpdatedEvent, value); }
170                 }
171                 
172                 public event GridViewUpdateEventHandler RowUpdating {
173                         add { Events.AddHandler (RowUpdatingEvent, value); }
174                         remove { Events.RemoveHandler (RowUpdatingEvent, value); }
175                 }
176                 
177                 public event EventHandler SelectedIndexChanged {
178                         add { Events.AddHandler (SelectedIndexChangedEvent, value); }
179                         remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
180                 }
181                 
182                 public event GridViewSelectEventHandler SelectedIndexChanging {
183                         add { Events.AddHandler (SelectedIndexChangingEvent, value); }
184                         remove { Events.RemoveHandler (SelectedIndexChangingEvent, value); }
185                 }
186                 
187                 public event EventHandler Sorted {
188                         add { Events.AddHandler (SortedEvent, value); }
189                         remove { Events.RemoveHandler (SortedEvent, value); }
190                 }
191                 
192                 public event GridViewSortEventHandler Sorting {
193                         add { Events.AddHandler (SortingEvent, value); }
194                         remove { Events.RemoveHandler (SortingEvent, value); }
195                 }
196                 
197                 protected virtual void OnPageIndexChanged (EventArgs e)
198                 {
199                         if (Events != null) {
200                                 EventHandler eh = (EventHandler) Events [PageIndexChangedEvent];
201                                 if (eh != null) eh (this, e);
202                         }
203                 }
204                 
205                 protected virtual void OnPageIndexChanging (GridViewPageEventArgs e)
206                 {
207                         if (Events != null) {
208                                 GridViewPageEventHandler eh = (GridViewPageEventHandler) Events [PageIndexChangingEvent];
209                                 if (eh != null) {
210                                         eh (this, e);
211                                         return;
212                                 }
213                         }
214                         if (!IsBoundUsingDataSourceID)
215                                 throw new HttpException (String.Format ("The GridView '{0}' fired event PageIndexChanging which wasn't handled.", ID));
216                 }
217                 
218                 protected virtual void OnRowCancelingEdit (GridViewCancelEditEventArgs e)
219                 {
220                         if (Events != null) {
221                                 GridViewCancelEditEventHandler eh = (GridViewCancelEditEventHandler) Events [RowCancelingEditEvent];
222                                 if (eh != null) {
223                                         eh (this, e);
224                                         return;
225                                 }
226                         }
227                         if (!IsBoundUsingDataSourceID)
228                                 throw new HttpException (String.Format ("The GridView '{0}' fired event RowCancelingEdit which wasn't handled.", ID));
229                 }
230                 
231                 protected virtual void OnRowCommand (GridViewCommandEventArgs e)
232                 {
233                         if (Events != null) {
234                                 GridViewCommandEventHandler eh = (GridViewCommandEventHandler) Events [RowCommandEvent];
235                                 if (eh != null) eh (this, e);
236                         }
237                 }
238                 
239                 protected virtual void OnRowCreated (GridViewRowEventArgs e)
240                 {
241                         if (Events != null) {
242                                 GridViewRowEventHandler eh = (GridViewRowEventHandler) Events [RowCreatedEvent];
243                                 if (eh != null) eh (this, e);
244                         }
245                 }
246                 
247                 protected virtual void OnRowDataBound (GridViewRowEventArgs e)
248                 {
249                         if (Events != null) {
250                                 GridViewRowEventHandler eh = (GridViewRowEventHandler) Events [RowDataBoundEvent];
251                                 if (eh != null) eh (this, e);
252                         }
253                 }
254                 
255                 protected virtual void OnRowDeleted (GridViewDeletedEventArgs e)
256                 {
257                         if (Events != null) {
258                                 GridViewDeletedEventHandler eh = (GridViewDeletedEventHandler) Events [RowDeletedEvent];
259                                 if (eh != null) eh (this, e);
260                         }
261                 }
262                 
263                 protected virtual void OnRowDeleting (GridViewDeleteEventArgs e)
264                 {
265                         if (Events != null) {
266                                 GridViewDeleteEventHandler eh = (GridViewDeleteEventHandler) Events [RowDeletingEvent];
267                                 if (eh != null) {
268                                         eh (this, e);
269                                         return;
270                                 }
271                         }
272                         if (!IsBoundUsingDataSourceID)
273                                 throw new HttpException (String.Format ("The GridView '{0}' fired event RowDeleting which wasn't handled.", ID));
274                 }
275                 
276                 protected virtual void OnRowEditing (GridViewEditEventArgs e)
277                 {
278                         if (Events != null) {
279                                 GridViewEditEventHandler eh = (GridViewEditEventHandler) Events [RowEditingEvent];
280                                 if (eh != null) {
281                                         eh (this, e);
282                                         return;
283                                 }
284                         }
285                         if (!IsBoundUsingDataSourceID)
286                                 throw new HttpException (String.Format ("The GridView '{0}' fired event RowEditing which wasn't handled.", ID));
287                 }
288                 
289                 protected virtual void OnRowUpdated (GridViewUpdatedEventArgs e)
290                 {
291                         if (Events != null) {
292                                 GridViewUpdatedEventHandler eh = (GridViewUpdatedEventHandler) Events [RowUpdatedEvent];
293                                 if (eh != null) eh (this, e);
294                         }
295                 }
296                 
297                 protected virtual void OnRowUpdating (GridViewUpdateEventArgs e)
298                 {
299                         if (Events != null) {
300                                 GridViewUpdateEventHandler eh = (GridViewUpdateEventHandler) Events [RowUpdatingEvent];
301                                 if (eh != null) {
302                                         eh (this, e);
303                                         return;
304                                 }
305                         }
306                         if (!IsBoundUsingDataSourceID)
307                                 throw new HttpException (String.Format ("The GridView '{0}' fired event RowUpdating which wasn't handled.", ID));
308                 }
309                 
310                 protected virtual void OnSelectedIndexChanged (EventArgs e)
311                 {
312                         if (Events != null) {
313                                 EventHandler eh = (EventHandler) Events [SelectedIndexChangedEvent];
314                                 if (eh != null) eh (this, e);
315                         }
316                 }
317                 
318                 protected virtual void OnSelectedIndexChanging (GridViewSelectEventArgs e)
319                 {
320                         if (Events != null) {
321                                 GridViewSelectEventHandler eh = (GridViewSelectEventHandler) Events [SelectedIndexChangingEvent];
322                                 if (eh != null) eh (this, e);
323                         }
324                 }
325                 
326                 protected virtual void OnSorted (EventArgs e)
327                 {
328                         if (Events != null) {
329                                 EventHandler eh = (EventHandler) Events [SortedEvent];
330                                 if (eh != null) eh (this, e);
331                         }
332                 }
333                 
334                 protected virtual void OnSorting (GridViewSortEventArgs e)
335                 {
336                         if (Events != null) {
337                                 GridViewSortEventHandler eh = (GridViewSortEventHandler) Events [SortingEvent];
338                                 if (eh != null) {
339                                         eh (this, e);
340                                         return;
341                                 }
342                         }
343                         if (!IsBoundUsingDataSourceID)
344                                 throw new HttpException (String.Format ("The GridView '{0}' fired event Sorting which wasn't handled.", ID));
345                 }
346                 
347                 
348                 [WebCategoryAttribute ("Paging")]
349                 [DefaultValueAttribute (false)]
350                 public virtual bool AllowPaging {
351                         get {
352                                 object ob = ViewState ["AllowPaging"];
353                                 if (ob != null)
354                                         return (bool) ob;
355                                 return false;
356                         }
357                         set {
358                                 if (value == AllowPaging)
359                                         return;
360                                 ViewState ["AllowPaging"] = value;
361                                 RequireBinding ();
362                         }
363                 }
364                 
365                 [WebCategoryAttribute ("Behavior")]
366                 [DefaultValueAttribute (false)]
367                 public virtual bool AllowSorting {
368                         get {
369                                 object ob = ViewState ["AllowSorting"];
370                                 if (ob != null)
371                                         return (bool) ob;
372                                 return false;
373                         }
374                         set {
375                                 if (value == AllowSorting)
376                                         return;
377                                 ViewState ["AllowSorting"] = value;
378                                 RequireBinding ();
379                         }
380                 }
381                 
382                 [WebCategoryAttribute ("Styles")]
383                 [PersistenceMode (PersistenceMode.InnerProperty)]
384                 [NotifyParentProperty (true)]
385                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
386                 public TableItemStyle AlternatingRowStyle {
387                         get {
388                                 if (alternatingRowStyle == null) {
389                                         alternatingRowStyle = new TableItemStyle ();
390                                         if (IsTrackingViewState)
391                                                 alternatingRowStyle.TrackViewState();
392                                 }
393                                 return alternatingRowStyle;
394                         }
395                 }
396
397                 [WebCategoryAttribute ("Behavior")]
398                 [DefaultValueAttribute (false)]
399                 public virtual bool AutoGenerateEditButton {
400                         get {
401                                 object ob = ViewState ["AutoGenerateEditButton"];
402                                 if (ob != null)
403                                         return (bool) ob;
404                                 return false;
405                         }
406                         set {
407                                 if (value == AutoGenerateEditButton)
408                                         return;
409                                 ViewState ["AutoGenerateEditButton"] = value;
410                                 RequireBinding ();
411                         }
412                 }
413
414                 [WebCategoryAttribute ("Behavior")]
415                 [DefaultValueAttribute (false)]
416                 public virtual bool AutoGenerateDeleteButton {
417                         get {
418                                 object ob = ViewState ["AutoGenerateDeleteButton"];
419                                 if (ob != null)
420                                         return (bool) ob;
421                                 return false;
422                         }
423                         set {
424                                 if (value == AutoGenerateDeleteButton)
425                                         return;
426                                 ViewState ["AutoGenerateDeleteButton"] = value;
427                                 RequireBinding ();
428                         }
429                 }
430
431                 [WebCategoryAttribute ("Behavior")]
432                 [DefaultValueAttribute (false)]
433                 public virtual bool AutoGenerateSelectButton {
434                         get {
435                                 object ob = ViewState ["AutoGenerateSelectButton"];
436                                 if (ob != null)
437                                         return (bool) ob;
438                                 return false;
439                         }
440                         set {
441                                 if (value == AutoGenerateSelectButton)
442                                         return;
443                                 ViewState ["AutoGenerateSelectButton"] = value;
444                                 RequireBinding ();
445                         }
446                 }
447
448                 [WebCategoryAttribute ("Behavior")]
449                 [DefaultValueAttribute (true)]
450                 public virtual bool AutoGenerateColumns {
451                         get {
452                                 object ob = ViewState ["AutoGenerateColumns"];
453                                 if (ob != null)
454                                         return (bool) ob;
455                                 return true;
456                         }
457                         set {
458                                 if (value == AutoGenerateColumns)
459                                         return;
460                                 ViewState ["AutoGenerateColumns"] = value;
461                                 RequireBinding ();
462                         }
463                 }
464                 
465                 [UrlPropertyAttribute]
466                 [WebCategoryAttribute ("Appearance")]
467                 [DefaultValueAttribute ("")]
468                 [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
469                 public virtual string BackImageUrl {
470                         get {
471                                 if (ControlStyleCreated)
472                                         return ((TableStyle) ControlStyle).BackImageUrl;
473                                 return String.Empty;
474                         }
475                         set { ((TableStyle) ControlStyle).BackImageUrl = value; }
476                 }
477
478                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
479                 [BrowsableAttribute (false)]
480                 public virtual GridViewRow BottomPagerRow {
481                         get {
482                                 EnsureDataBound ();
483                                 return bottomPagerRow;
484                         }
485                 }
486         
487                 [WebCategoryAttribute ("Accessibility")]
488                 [DefaultValueAttribute ("")]
489                 [LocalizableAttribute (true)]
490                 public virtual string Caption {
491                         get {
492                                 object ob = ViewState ["Caption"];
493                                 if (ob != null)
494                                         return (string) ob;
495                                 return String.Empty;
496                         }
497                         set { ViewState ["Caption"] = value; }
498                 }
499                 
500                 [WebCategoryAttribute ("Accessibility")]
501                 [DefaultValueAttribute (TableCaptionAlign.NotSet)]
502                 public virtual TableCaptionAlign CaptionAlign
503                 {
504                         get {
505                                 object o = ViewState ["CaptionAlign"];
506                                 if(o != null)
507                                         return (TableCaptionAlign) o;
508                                 return TableCaptionAlign.NotSet;
509                         }
510                         set { ViewState ["CaptionAlign"] = value; }
511                 }
512
513                 [WebCategoryAttribute ("Layout")]
514                 [DefaultValueAttribute (-1)]
515                 public virtual int CellPadding
516                 {
517                         get {
518                                 if (ControlStyleCreated)
519                                         return ((TableStyle) ControlStyle).CellPadding;
520                                 return -1;
521                         }
522                         set { ((TableStyle) ControlStyle).CellPadding = value; }
523                 }
524
525                 [WebCategoryAttribute ("Layout")]
526                 [DefaultValueAttribute (0)]
527                 public virtual int CellSpacing
528                 {
529                         get {
530                                 if (ControlStyleCreated)
531                                         return ((TableStyle) ControlStyle).CellSpacing;
532                                 return 0;
533                         }
534                         set { ((TableStyle) ControlStyle).CellSpacing = value; }
535                 }
536                 
537                 [EditorAttribute ("System.Web.UI.Design.WebControls.DataControlFieldTypeEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
538                 [MergablePropertyAttribute (false)]
539                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
540                 [DefaultValueAttribute (null)]
541                 [WebCategoryAttribute ("Misc")]
542                 public virtual DataControlFieldCollection Columns {
543                         get {
544                                 if (columns == null) {
545                                         columns = new DataControlFieldCollection ();
546                                         columns.FieldsChanged += new EventHandler (OnFieldsChanged);
547                                         if (IsTrackingViewState)
548                                                 ((IStateManager)columns).TrackViewState ();
549                                 }
550                                 return columns;
551                         }
552                 }
553
554                 [BrowsableAttribute(false)]
555                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
556                 public IAutoFieldGenerator ColumnsGenerator {
557                         get;
558                         set;
559                 }
560
561                 [DefaultValueAttribute (null)]
562                 [WebCategoryAttribute ("Data")]
563                 [TypeConverter (typeof(StringArrayConverter))]
564                 [EditorAttribute ("System.Web.UI.Design.WebControls.DataFieldEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
565                 public virtual string[] DataKeyNames {
566                         get {
567                                 if (dataKeyNames != null)
568                                         return dataKeyNames;
569                                 return emptyKeys;
570                         }
571                         set {
572                                 dataKeyNames = value;
573                                 RequireBinding ();
574                         }
575                 }
576
577                 List <DataKey> DataKeyList {
578                         get {
579                                 if (_dataKeyList == null)
580                                         _dataKeyList = new List <DataKey> ();
581                                 
582                                 return _dataKeyList;
583                         }
584                 }
585                 List <DataKey> DataKeySuffixList {
586                         get {
587                                 if (_dataKeySuffixList == null)
588                                         _dataKeySuffixList = new List <DataKey> ();
589                                 
590                                 return _dataKeySuffixList;
591                         }
592                 }
593                 [BrowsableAttribute (false)]
594                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
595                 public virtual DataKeyArray DataKeys {
596                         get {
597                                 if (keys == null) {
598                                         keys = new DataKeyArray (DataKeyList);
599                                         if (IsTrackingViewState)
600                                                 ((IStateManager) keys).TrackViewState ();
601                                 }
602                                 return keys;
603                         }
604                 }
605
606                 DataKey OldEditValues {
607                         get {
608                                 if (oldEditValues == null) {
609                                         oldEditValues = new DataKey (new OrderedDictionary ());
610                                 }
611                                 return oldEditValues;
612                         }
613                 }
614
615                 [WebCategoryAttribute ("Misc")]
616                 [DefaultValueAttribute (-1)]
617                 public virtual int EditIndex {
618                         get { return editIndex; }
619                         set {
620                                 if (value == editIndex)
621                                         return;
622                                 editIndex = value;
623                                 RequireBinding ();
624                         }
625                 }
626         
627                 [WebCategoryAttribute ("Styles")]
628                 [PersistenceMode (PersistenceMode.InnerProperty)]
629                 [NotifyParentProperty (true)]
630                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
631                 public TableItemStyle EditRowStyle {
632                         get {
633                                 if (editRowStyle == null) {
634                                         editRowStyle = new TableItemStyle ();
635                                         if (IsTrackingViewState)
636                                                 editRowStyle.TrackViewState();
637                                 }
638                                 return editRowStyle;
639                         }
640                 }
641                 
642                 [WebCategoryAttribute ("Styles")]
643                 [PersistenceMode (PersistenceMode.InnerProperty)]
644                 [NotifyParentProperty (true)]
645                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
646                 public TableItemStyle EmptyDataRowStyle {
647                         get {
648                                 if (emptyDataRowStyle == null) {
649                                         emptyDataRowStyle = new TableItemStyle ();
650                                         if (IsTrackingViewState)
651                                                 emptyDataRowStyle.TrackViewState();
652                                 }
653                                 return emptyDataRowStyle;
654                         }
655                 }
656                 
657                 [DefaultValue (null)]
658                 [TemplateContainer (typeof(GridViewRow), BindingDirection.OneWay)]
659                 [PersistenceMode (PersistenceMode.InnerProperty)]
660                 [Browsable (false)]
661                 public virtual ITemplate EmptyDataTemplate {
662                         get { return emptyDataTemplate; }
663                         set { emptyDataTemplate = value; }
664                 }
665                 
666                 [LocalizableAttribute (true)]
667                 [WebCategoryAttribute ("Appearance")]
668                 [DefaultValueAttribute ("")]
669                 public virtual string EmptyDataText {
670                         get {
671                                 object ob = ViewState ["EmptyDataText"];
672                                 if (ob != null)
673                                         return (string) ob;
674                                 return String.Empty;
675                         }
676                         set {
677                                 if (value == EmptyDataText)
678                                         return;
679                                 ViewState ["EmptyDataText"] = value;
680                                 RequireBinding ();
681                         }
682                 }
683         
684                 [WebCategoryAttribute ("Behavior")]
685                 [DefaultValueAttribute (false)]
686                 public virtual bool EnableSortingAndPagingCallbacks {
687                         get {
688                                 object ob = ViewState ["EnableSortingAndPagingCallbacks"];
689                                 if (ob != null)
690                                         return (bool) ob;
691                                 return false;
692                         }
693                         set {
694                                 if (value == EnableSortingAndPagingCallbacks)
695                                         return;
696                                 ViewState ["EnableSortingAndPagingCallbacks"] = value;
697                                 RequireBinding ();
698                         }
699                 }
700
701                 [MonoTODO ("Make use of it in the code")]
702                 [DefaultValue (true)]
703                 public virtual bool EnableModelValidation {
704                         get;
705                         set;
706                 }
707                 
708                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
709                 [BrowsableAttribute (false)]
710                 public virtual GridViewRow FooterRow {
711                         get {
712                                 if (table != null) {
713                                         for (int index = table.Rows.Count - 1; index >= 0; index--) {
714                                                 GridViewRow row = (GridViewRow) table.Rows [index];
715                                                 switch (row.RowType) {
716                                                         case DataControlRowType.Separator:
717                                                         case DataControlRowType.Pager:
718                                                                 continue;
719                                                         case DataControlRowType.Footer:
720                                                                 return row;
721                                                         default:
722                                                                 break;
723                                                 }
724                                         }
725                                 }
726                                 return null;
727                         }
728                 }
729         
730                 [WebCategoryAttribute ("Styles")]
731                 [PersistenceMode (PersistenceMode.InnerProperty)]
732                 [NotifyParentProperty (true)]
733                 [DefaultValue (null)]
734                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
735                 public TableItemStyle FooterStyle {
736                         get {
737                                 if (footerStyle == null) {
738                                         footerStyle = new TableItemStyle ();
739                                         if (IsTrackingViewState)
740                                                 footerStyle.TrackViewState();
741                                 }
742                                 return footerStyle;
743                         }
744                 }
745                 
746                 [WebCategoryAttribute ("Appearance")]
747                 [DefaultValueAttribute (GridLines.Both)]
748                 public virtual GridLines GridLines {
749                         get {
750                                 if (ControlStyleCreated)
751                                         return ((TableStyle) ControlStyle).GridLines;
752                                 return GridLines.Both;
753                         }
754                         set { ((TableStyle) ControlStyle).GridLines = value; }
755                 }
756
757                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
758                 [BrowsableAttribute (false)]
759                 public virtual GridViewRow HeaderRow {
760                         get {
761                                 if (table != null) {
762                                         for (int index = 0, total = table.Rows.Count; index < total; index++) {
763                                                 GridViewRow row = (GridViewRow) table.Rows [index];
764                                                 switch (row.RowType) {
765                                                         case DataControlRowType.Separator:
766                                                         case DataControlRowType.Pager:
767                                                                 continue;
768                                                         case DataControlRowType.Header:
769                                                                 return row;
770                                                         default:
771                                                                 break;
772                                                 }
773                                         }
774                                 }
775                                 return null;
776                         }
777                 }
778         
779                 [WebCategoryAttribute ("Styles")]
780                 [PersistenceMode (PersistenceMode.InnerProperty)]
781                 [NotifyParentProperty (true)]
782                 [DefaultValue (null)]
783                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
784                 public TableItemStyle HeaderStyle {
785                         get {
786                                 if (headerStyle == null) {
787                                         headerStyle = new TableItemStyle ();
788                                         if (IsTrackingViewState)
789                                                 headerStyle.TrackViewState();
790                                 }
791                                 return headerStyle;
792                         }
793                 }
794                 
795                 [Category ("Layout")]
796                 [DefaultValueAttribute (HorizontalAlign.NotSet)]
797                 public virtual HorizontalAlign HorizontalAlign {
798                         get {
799                                 if (ControlStyleCreated)
800                                         return ((TableStyle) ControlStyle).HorizontalAlign;
801                                 return HorizontalAlign.NotSet;
802                         }
803                         set { ((TableStyle) ControlStyle).HorizontalAlign = value; }
804                 }
805
806                 [BrowsableAttribute (false)]
807                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
808                 public virtual int PageCount {
809                         get { return pageCount; }
810                         private set { pageCount = value; }
811                 }
812
813                 [WebCategoryAttribute ("Paging")]
814                 [BrowsableAttribute (true)]
815                 [DefaultValueAttribute (0)]
816                 public virtual int PageIndex {
817                         get { return pageIndex; }
818                         set {
819                                 if (value == pageIndex)
820                                         return;
821                                 pageIndex = value;
822                                 RequireBinding ();
823                         }
824                 }
825         
826                 [DefaultValueAttribute (10)]
827                 [WebCategoryAttribute ("Paging")]
828                 public virtual int PageSize {
829                         get {
830                                 object ob = ViewState ["PageSize"];
831                                 if (ob != null)
832                                         return (int) ob;
833                                 return 10;
834                         }
835                         set {
836                                 if (value == PageSize)
837                                         return;
838                                 ViewState ["PageSize"] = value;
839                                 RequireBinding ();
840                         }
841                 }
842         
843                 [WebCategoryAttribute ("Paging")]
844                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
845                 [NotifyParentPropertyAttribute (true)]
846                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
847                 public virtual PagerSettings PagerSettings {
848                         get {
849                                 if (pagerSettings == null) {
850                                         pagerSettings = new PagerSettings (this);
851                                         if (IsTrackingViewState)
852                                                 ((IStateManager)pagerSettings).TrackViewState ();
853                                 }
854                                 return pagerSettings;
855                         }
856                 }
857         
858                 [WebCategoryAttribute ("Styles")]
859                 [PersistenceMode (PersistenceMode.InnerProperty)]
860                 [NotifyParentProperty (true)]
861                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
862                 public TableItemStyle PagerStyle {
863                         get {
864                                 if (pagerStyle == null) {
865                                         pagerStyle = new TableItemStyle ();
866                                         if (IsTrackingViewState)
867                                                 pagerStyle.TrackViewState();
868                                 }
869                                 return pagerStyle;
870                         }
871                 }
872                 
873                 
874                 [DefaultValue (null)]
875                 [PersistenceMode (PersistenceMode.InnerProperty)]
876                 [Browsable (false)]
877                 [TemplateContainerAttribute(typeof(GridViewRow))]
878                 public virtual ITemplate PagerTemplate {
879                         get { return pagerTemplate; }
880                         set { pagerTemplate = value; }
881                 }
882                 
883                 [DefaultValueAttribute ("")]
884                 [WebCategoryAttribute ("Accessibility")]
885                 //              [TypeConverterAttribute (typeof(System.Web.UI.Design.DataColumnSelectionConverter)]
886                 public virtual string RowHeaderColumn {
887                         get {
888                                 object ob = ViewState ["RowHeaderColumn"];
889                                 if (ob != null)
890                                         return (string) ob;
891                                 return String.Empty;
892                         }
893                         set {
894                                 if (value == RowHeaderColumn)
895                                         return;
896                                 ViewState ["RowHeaderColumn"] = value;
897                                 RequireBinding ();
898                         }
899                 }
900                 
901                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
902                 [BrowsableAttribute (false)]
903                 public virtual GridViewRowCollection Rows {
904                         get {
905                                 EnsureChildControls ();
906                                 if (rows == null)
907                                         rows = new GridViewRowCollection (new ArrayList ());
908                                 return rows;
909                         }
910                 }
911                 
912                 [WebCategoryAttribute ("Styles")]
913                 [PersistenceMode (PersistenceMode.InnerProperty)]
914                 [NotifyParentProperty (true)]
915                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
916                 public TableItemStyle RowStyle {
917                         get {
918                                 if (rowStyle == null) {
919                                         rowStyle = new TableItemStyle ();
920                                         if (IsTrackingViewState)
921                                                 rowStyle.TrackViewState();
922                                 }
923                                 return rowStyle;
924                         }
925                 }
926                 
927                 [BrowsableAttribute (false)]
928                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
929                 public virtual DataKey SelectedDataKey {
930                         get {
931                                 if (DataKeyNames.Length == 0)
932                                         throw new InvalidOperationException (String.Format ("Data keys must be specified on GridView '{0}' before the selected data keys can be retrieved.  Use the DataKeyNames property to specify data keys.", ID));
933
934                                 if (selectedIndex >= 0 && selectedIndex < DataKeys.Count)
935                                         return DataKeys [selectedIndex];
936                                 else
937                                         return null;
938                         }
939                 }
940
941                 [MonoTODO]
942                 [Browsable(false)]
943                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
944                 public virtual DataKey SelectedPersistedDataKey {
945                         get; set;
946                 }
947
948                 [MonoTODO]
949                 DataKey IPersistedSelector.DataKey {
950                         get { return SelectedPersistedDataKey; }
951                         set { SelectedPersistedDataKey = value; }
952                 }
953                 
954                 [BindableAttribute (true)]
955                 [DefaultValueAttribute (-1)]
956                 public virtual int SelectedIndex {
957                         get { return selectedIndex; }
958                         set {
959                                 if (rows != null && selectedIndex >= 0 && selectedIndex < Rows.Count) {
960                                         int oldIndex = selectedIndex;
961                                         selectedIndex = -1;
962                                         Rows [oldIndex].RowState = GetRowState (oldIndex);
963                                 }
964                                 selectedIndex = value;
965                                 if (rows != null && selectedIndex >= 0 && selectedIndex < Rows.Count)
966                                         Rows [selectedIndex].RowState = GetRowState (selectedIndex);
967                         }
968                 }
969         
970                 [BrowsableAttribute (false)]
971                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
972                 public virtual GridViewRow SelectedRow {
973                         get {
974                                 if (selectedIndex >= 0 && selectedIndex < Rows.Count)
975                                         return Rows [selectedIndex];
976                                 else
977                                         return null;
978                         }
979                 }
980                 
981                 [WebCategoryAttribute ("Styles")]
982                 [PersistenceMode (PersistenceMode.InnerProperty)]
983                 [NotifyParentProperty (true)]
984                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
985                 public TableItemStyle SelectedRowStyle {
986                         get {
987                                 if (selectedRowStyle == null) {
988                                         selectedRowStyle = new TableItemStyle ();
989                                         if (IsTrackingViewState)
990                                                 selectedRowStyle.TrackViewState();
991                                 }
992                                 return selectedRowStyle;
993                         }
994                 }
995                 
996                 [BrowsableAttribute (false)]
997                 public object SelectedValue {
998                         get {
999                                 if (SelectedDataKey != null)
1000                                         return SelectedDataKey.Value;
1001                                 else
1002                                         return null;
1003                         }
1004                 }
1005                 
1006                 [WebCategoryAttribute ("Appearance")]
1007                 [DefaultValueAttribute (false)]
1008                 public virtual bool ShowFooter {
1009                         get {
1010                                 object ob = ViewState ["ShowFooter"];
1011                                 if (ob != null)
1012                                         return (bool) ob;
1013                                 return false;
1014                         }
1015                         set {
1016                                 if (value == ShowFooter)
1017                                         return;
1018                                 ViewState ["ShowFooter"] = value;
1019                                 RequireBinding ();
1020                         }
1021                 }
1022         
1023                 [WebCategoryAttribute ("Appearance")]
1024                 [DefaultValueAttribute (true)]
1025                 public virtual bool ShowHeader {
1026                         get {
1027                                 object ob = ViewState ["ShowHeader"];
1028                                 if (ob != null)
1029                                         return (bool) ob;
1030                                 return true;
1031                         }
1032                         set {
1033                                 if (value == ShowHeader)
1034                                         return;
1035                                 ViewState ["ShowHeader"] = value;
1036                                 RequireBinding ();
1037                         }
1038                 }
1039                 
1040                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
1041                 [BrowsableAttribute (false)]
1042                 [DefaultValueAttribute (SortDirection.Ascending)]
1043                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
1044                 public virtual SortDirection SortDirection {
1045                         get { return sortDirection; }
1046                         private set {
1047                                 if (sortDirection == value)
1048                                         return;
1049                                 sortDirection = value;
1050                                 RequireBinding ();
1051                         }
1052                 }
1053                 
1054                 [BrowsableAttribute (false)]
1055                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
1056                 public virtual string SortExpression {
1057                         get {
1058                                 if (sortExpression == null)
1059                                         return String.Empty;
1060                                 return sortExpression;
1061                         }
1062                         private set {
1063                                 if (sortExpression == value)
1064                                         return;
1065                                 sortExpression = value;
1066                                 RequireBinding ();
1067                         }
1068                 }
1069                 
1070                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
1071                 [BrowsableAttribute (false)]
1072                 public virtual GridViewRow TopPagerRow {
1073                         get {
1074                                 EnsureDataBound ();
1075                                 return topPagerRow;
1076                         }
1077                 }
1078         
1079                 [WebCategoryAttribute ("Accessibility")]
1080                 [DefaultValueAttribute (true)]
1081                 public virtual bool UseAccessibleHeader {
1082                         get {
1083                                 object ob = ViewState ["UseAccessibleHeader"];
1084                                 if (ob != null)
1085                                         return (bool) ob;
1086                                 return true;
1087                         }
1088                         set {
1089                                 if (value == UseAccessibleHeader)
1090                                         return;
1091                                 ViewState ["UseAccessibleHeader"] = value;
1092                                 RequireBinding ();
1093                         }
1094                 }
1095                 [TypeConverter (typeof(StringArrayConverter))]
1096                 [DefaultValue (null)]
1097                 public virtual string[] ClientIDRowSuffix {
1098                         get;
1099                         set;
1100                 }
1101
1102                 [BrowsableAttribute(false)]
1103                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
1104                 public DataKeyArray ClientIDRowSuffixDataKeys {
1105                         get {
1106                                 if (rowSuffixKeys == null) {
1107                                         rowSuffixKeys = new DataKeyArray (DataKeySuffixList);
1108                                         if (IsTrackingViewState)
1109                                                 ((IStateManager) rowSuffixKeys).TrackViewState ();
1110                                 }
1111
1112                                 return rowSuffixKeys;
1113                         }
1114                 }
1115
1116                 [DefaultValue (false)]
1117                 public virtual bool EnablePersistedSelection {
1118                         get {
1119                                 throw new NotImplementedException ();
1120                         }
1121                         
1122                         set {
1123                                 throw new NotImplementedException ();
1124                         }
1125                 }
1126
1127                 IAutoFieldGenerator IFieldControl.FieldsGenerator {
1128                         get {
1129                                 throw new NotImplementedException ();
1130                         }
1131                         
1132                         set {
1133                                 throw new NotImplementedException ();
1134                         }
1135                 }
1136
1137                 [DefaultValue (false)]
1138                 public virtual bool ShowHeaderWhenEmpty {
1139                         get { return ViewState.GetBool ("ShowHeaderWhenEmpty", false); }
1140                         set {
1141                                 if (value == ShowHeaderWhenEmpty)
1142                                         return;
1143                                 
1144                                 ViewState ["ShowHeaderWhenEmpty"] = value;
1145                                 RequireBinding ();
1146                         }
1147                 }
1148
1149                 [PersistenceMode (PersistenceMode.InnerProperty)]
1150                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
1151                 [NotifyParentProperty (true)]
1152                 public TableItemStyle SortedAscendingCellStyle {
1153                         get {
1154                                 if (sortedAscendingCellStyle == null) {
1155                                         sortedAscendingCellStyle = new TableItemStyle ();
1156                                         if (IsTrackingViewState)
1157                                                 ((IStateManager)sortedAscendingCellStyle).TrackViewState ();
1158                                 }
1159
1160                                 return sortedAscendingCellStyle;
1161                         }
1162                 }
1163
1164                 [PersistenceMode (PersistenceMode.InnerProperty)]
1165                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
1166                 [NotifyParentProperty (true)]
1167                 public TableItemStyle SortedAscendingHeaderStyle {
1168                         get {
1169                                 if (sortedAscendingHeaderStyle == null) {
1170                                         sortedAscendingHeaderStyle = new TableItemStyle ();
1171                                         if (IsTrackingViewState)
1172                                                 ((IStateManager)sortedAscendingHeaderStyle).TrackViewState ();
1173                                 }
1174
1175                                 return sortedAscendingHeaderStyle;
1176                         }
1177                 }
1178
1179                 [PersistenceMode (PersistenceMode.InnerProperty)]
1180                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
1181                 [NotifyParentProperty (true)]
1182                 public TableItemStyle SortedDescendingCellStyle {
1183                         get {
1184                                 if (sortedDescendingCellStyle == null) {
1185                                         sortedDescendingCellStyle = new TableItemStyle ();
1186                                         if (IsTrackingViewState)
1187                                                 ((IStateManager)sortedDescendingCellStyle).TrackViewState ();
1188                                 }
1189
1190                                 return sortedDescendingCellStyle;
1191                         }
1192                 }
1193
1194                 [PersistenceMode (PersistenceMode.InnerProperty)]
1195                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
1196                 [NotifyParentProperty (true)]
1197                 public TableItemStyle SortedDescendingHeaderStyle {
1198                         get {
1199                                 if (sortedDescendingHeaderStyle == null) {
1200                                         sortedDescendingHeaderStyle = new TableItemStyle ();
1201                                         if (IsTrackingViewState)
1202                                                 ((IStateManager)sortedDescendingHeaderStyle).TrackViewState ();
1203                                 }
1204
1205                                 return sortedDescendingHeaderStyle;
1206                         }
1207                 }               
1208                 public virtual bool IsBindableType (Type type)
1209                 {
1210                         return type.IsPrimitive || type == typeof (string) || type == typeof (decimal) || type == typeof (DateTime) || type == typeof (Guid);
1211                 }
1212                 
1213                 // MSDN: The CreateDataSourceSelectArguments method is a helper method called by 
1214                 // the GridView control to create the DataSourceSelectArguments object that 
1215                 // contains the arguments passed to the data source. In this implementation, 
1216                 // the DataSourceSelectArguments object contains the arguments for paging operations.
1217                 protected override DataSourceSelectArguments CreateDataSourceSelectArguments ()
1218                 {
1219                         DataSourceSelectArguments arg = DataSourceSelectArguments.Empty;
1220                         DataSourceView view= GetData();
1221                         if (AllowPaging && view.CanPage) {
1222                                 arg.StartRowIndex = PageIndex * PageSize;
1223                                 if (view.CanRetrieveTotalRowCount) {
1224                                         arg.RetrieveTotalRowCount = true;
1225                                         arg.MaximumRows = PageSize;
1226                                 } else
1227                                         arg.MaximumRows = -1;
1228                         }
1229
1230                         if (IsBoundUsingDataSourceID && !String.IsNullOrEmpty (sortExpression)) {
1231                                 if (sortDirection == SortDirection.Ascending)
1232                                         arg.SortExpression = sortExpression;
1233                                 else
1234                                         arg.SortExpression = sortExpression + " DESC";
1235                         }
1236                         
1237                         return arg;
1238                 }
1239                 
1240                 protected virtual ICollection CreateColumns (PagedDataSource dataSource, bool useDataSource)
1241                 {
1242                         bool autoGenerate = AutoGenerateColumns;
1243
1244                         if (autoGenerate) {
1245                                 IAutoFieldGenerator fieldGenerator = ColumnsGenerator;
1246                                 if (fieldGenerator != null)
1247                                         return fieldGenerator.GenerateFields (this);
1248                         }
1249                         
1250                         ArrayList fields = new ArrayList ();
1251                         
1252                         if (AutoGenerateEditButton || AutoGenerateDeleteButton || AutoGenerateSelectButton) {
1253                                 CommandField field = new CommandField ();
1254                                 field.ShowEditButton = AutoGenerateEditButton;
1255                                 field.ShowDeleteButton = AutoGenerateDeleteButton;
1256                                 field.ShowSelectButton = AutoGenerateSelectButton;
1257                                 fields.Add (field);
1258                         }
1259
1260                         fields.AddRange (Columns);
1261                         
1262                         if (autoGenerate) {
1263                                 if (useDataSource)
1264                                         autoFieldProperties = CreateAutoFieldProperties (dataSource);
1265         
1266                                 if (autoFieldProperties != null) {
1267                                         foreach (AutoGeneratedFieldProperties props in autoFieldProperties)
1268                                                 fields.Add (CreateAutoGeneratedColumn (props));
1269                                 }
1270                         }
1271                         
1272                         return fields;
1273                 }
1274                 
1275                 protected virtual AutoGeneratedField CreateAutoGeneratedColumn (AutoGeneratedFieldProperties fieldProperties)
1276                 {
1277                         return new AutoGeneratedField (fieldProperties);
1278                 }
1279                 
1280                 AutoGeneratedFieldProperties[] CreateAutoFieldProperties (PagedDataSource source)
1281                 {
1282                         if(source == null) return null;
1283                         
1284                         PropertyDescriptorCollection props = source.GetItemProperties (new PropertyDescriptor[0]);
1285                         Type prop_type = null;
1286                         
1287                         var retVal = new List <AutoGeneratedFieldProperties> ();
1288                         
1289                         if (props == null) {
1290                                 object fitem = null;
1291                                 PropertyInfo prop_item =  source.DataSource.GetType().GetProperty("Item",
1292                                                                                                   BindingFlags.Instance | BindingFlags.Static |
1293                                                                                                   BindingFlags.Public, null, null,
1294                                                                                                   new Type[] { typeof(int) }, null);
1295                                 
1296                                 if (prop_item != null)
1297                                         prop_type = prop_item.PropertyType;
1298                                 
1299                                 if (prop_type == null || prop_type == typeof(object)) {
1300                                         IEnumerator en = source.GetEnumerator();
1301                                         if (en != null && en.MoveNext ()) {
1302                                                 fitem = en.Current;
1303                                                 _dataEnumerator = en;
1304                                         }
1305                                         if (fitem != null)
1306                                                 prop_type = fitem.GetType();
1307                                 }
1308                                 
1309                                 if (fitem != null && fitem is ICustomTypeDescriptor)
1310                                         props = TypeDescriptor.GetProperties(fitem);
1311                                 else if (prop_type != null) {
1312                                         if (IsBindableType (prop_type)) {
1313                                                 AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1314                                                 ((IStateManager)field).TrackViewState();
1315                                                 field.Name = "Item";
1316                                                 field.DataField = BoundField.ThisExpression;
1317                                                 field.Type = prop_type;
1318                                                 retVal.Add (field);
1319                                         } else
1320                                                 props = TypeDescriptor.GetProperties (prop_type);
1321                                 }
1322                         }
1323                         
1324                         if (props != null && props.Count > 0) {
1325                                 foreach (PropertyDescriptor current in props) {
1326                                         if (IsBindableType (current.PropertyType) && (prop_type == null || current.ComponentType == prop_type)) {
1327                                                 AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1328                                                 ((IStateManager)field).TrackViewState();
1329                                                 field.Name = current.Name;
1330                                                 field.DataField = current.Name;
1331                                                 for (int i = 0; i < DataKeyNames.Length; i++) {
1332                                                         if (string.Compare (DataKeyNames [i], current.Name, StringComparison.InvariantCultureIgnoreCase) == 0) {
1333                                                                 field.IsReadOnly = true;
1334                                                                 break;
1335                                                         }
1336                                                 }
1337                                                 field.Type = current.PropertyType;
1338                                                 retVal.Add (field);
1339                                         }
1340                                 }
1341                         }
1342
1343                         if (retVal.Count > 0)
1344                                 return retVal.ToArray ();
1345                         else
1346                                 return new AutoGeneratedFieldProperties [0];
1347                 }
1348                 
1349                 protected virtual GridViewRow CreateRow (int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState)
1350                 {
1351                         GridViewRow row = new GridViewRow (rowIndex, dataSourceIndex, rowType, rowState);
1352                         return row;
1353                 }
1354                 
1355                 void RequireBinding ()
1356                 {
1357                         if (Initialized)
1358                                 RequiresDataBinding = true;
1359                 }
1360                 
1361                 protected virtual Table CreateChildTable ()
1362                 {
1363                         return new ContainedTable (this);
1364                 }
1365
1366                 void CreateHeaderRow (Table mainTable, DataControlField[] fields, bool dataBinding)
1367                 {
1368                         GridViewRow headerRow = CreateRow (-1, -1, DataControlRowType.Header, DataControlRowState.Normal);
1369                         InitializeRow (headerRow, fields);
1370                         OnRowCreated (new GridViewRowEventArgs (headerRow));
1371                         mainTable.Rows.Add (headerRow);
1372                         if (dataBinding) {
1373                                 headerRow.DataBind ();
1374                                 OnRowDataBound (new GridViewRowEventArgs (headerRow));
1375                         }
1376                 }
1377                 
1378                 protected override int CreateChildControls (IEnumerable data, bool dataBinding)
1379                 {
1380                         // clear GridView
1381                         Controls.Clear ();
1382                         table = null;
1383                         rows = null;
1384
1385                         if (data == null)
1386                                 return 0;
1387
1388                         PagedDataSource dataSource;
1389
1390                         if (dataBinding) {
1391                                 DataSourceView view = GetData ();
1392                                 dataSource = new PagedDataSource ();
1393                                 dataSource.DataSource = data;
1394                                 
1395                                 if (AllowPaging) {
1396                                         dataSource.AllowPaging = true;
1397                                         dataSource.PageSize = PageSize;
1398                                         if (view.CanPage) {
1399                                                 dataSource.AllowServerPaging = true;
1400                                                 if (SelectArguments.RetrieveTotalRowCount)
1401                                                         dataSource.VirtualCount = SelectArguments.TotalRowCount;
1402                                         }
1403                                         if (PageIndex >= dataSource.PageCount)
1404                                                 pageIndex = dataSource.PageCount - 1;
1405                                         dataSource.CurrentPageIndex = PageIndex;
1406                                 }
1407                                 
1408                                 PageCount = dataSource.PageCount;
1409                         } else {
1410                                 dataSource = new PagedDataSource ();
1411                                 dataSource.DataSource = data;
1412                                 if (AllowPaging) {
1413                                         dataSource.AllowPaging = true;
1414                                         dataSource.PageSize = PageSize;
1415                                         dataSource.CurrentPageIndex = PageIndex;
1416                                 }
1417                         }
1418
1419                         bool createPager = AllowPaging && (PageCount >= 1) && PagerSettings.Visible;
1420
1421                         ArrayList list = new ArrayList ();
1422                         
1423                         // Creates the set of fields to show
1424
1425                         _dataEnumerator = null;
1426                         ICollection fieldCollection = CreateColumns (dataSource, dataBinding);
1427                         int fieldCount = fieldCollection.Count;
1428                         DataControlField dcf;
1429                         DataControlField[] fields = new DataControlField [fieldCount];
1430                         fieldCollection.CopyTo (fields, 0);
1431                         
1432                         for (int i = 0; i < fieldCount; i++) {
1433                                 dcf = fields [i];
1434                                 dcf.Initialize (AllowSorting, this);
1435                                 if (EnableSortingAndPagingCallbacks)
1436                                         dcf.ValidateSupportsCallback ();
1437                         }
1438
1439                         bool skip_first = false;
1440                         IEnumerator enumerator;
1441                         if (_dataEnumerator != null) {
1442                                 // replaced when creating bound columns
1443                                 enumerator = _dataEnumerator;
1444                                 skip_first = true;
1445                         } else
1446                                 enumerator = dataSource.GetEnumerator ();
1447
1448                         // Main table creation
1449                         Table mainTable = ContainedTable;
1450                         List <DataKey> dataKeyList;
1451                         string[] dataKeyNames;
1452                         List <DataKey> dataKeySuffixList;
1453                         string[] clientIDRowSuffix;
1454                         if (dataBinding) {
1455                                 dataKeyList = DataKeyList;
1456                                 dataKeyNames = DataKeyNames;
1457                                 dataKeySuffixList = DataKeySuffixList;
1458                                 clientIDRowSuffix = ClientIDRowSuffix;
1459                         } else {
1460                                 dataKeyList = null;
1461                                 dataKeyNames = null;
1462                                 dataKeySuffixList = null;
1463                                 clientIDRowSuffix = null;
1464                         }
1465
1466                         while (skip_first || enumerator.MoveNext ()) {
1467                                 skip_first = false;
1468                                 object obj = enumerator.Current;
1469                                 
1470                                 if (list.Count == 0) {
1471                                         if (createPager && (PagerSettings.Position == PagerPosition.Top || PagerSettings.Position == PagerPosition.TopAndBottom)) {
1472                                                 topPagerRow = CreatePagerRow (fieldCount, dataSource);
1473                                                 OnRowCreated (new GridViewRowEventArgs (topPagerRow));
1474                                                 mainTable.Rows.Add (topPagerRow);
1475                                                 if (dataBinding) {
1476                                                         topPagerRow.DataBind ();
1477                                                         OnRowDataBound (new GridViewRowEventArgs (topPagerRow));
1478                                                 }
1479                                                 if (PageCount == 1)
1480                                                         topPagerRow.Visible = false;
1481                                         }
1482
1483                                         if (ShowHeader)
1484                                                 CreateHeaderRow (mainTable, fields, dataBinding);
1485                                 }
1486                                 
1487                                 DataControlRowState rstate = GetRowState (list.Count);
1488                                 GridViewRow row = CreateRow (list.Count, list.Count, DataControlRowType.DataRow, rstate);
1489                                 row.DataItem = obj;
1490                                 list.Add (row);
1491                                 InitializeRow (row, fields);
1492                                 OnRowCreated (new GridViewRowEventArgs (row));
1493                                 mainTable.Rows.Add (row);
1494                                 if (dataBinding) {
1495                                         row.DataBind ();                                        
1496                                         if (EditIndex == row.RowIndex)
1497                                                 oldEditValues = new DataKey (GetRowValues (row, true, true));
1498                                         dataKeyList.Add (new DataKey (CreateRowDataKey (row), dataKeyNames));
1499                                         dataKeySuffixList.Add (new DataKey (CreateRowSuffixDataKey (row), clientIDRowSuffix));
1500                                         OnRowDataBound (new GridViewRowEventArgs (row));
1501                                 } 
1502                         }
1503
1504                         if (list.Count == 0) {
1505                                 if (ShowHeader && ShowHeaderWhenEmpty)
1506                                         CreateHeaderRow (mainTable, fields, dataBinding);
1507                                 GridViewRow emptyRow = CreateEmptyrRow (fieldCount);
1508                                 if (emptyRow != null) {
1509                                         OnRowCreated (new GridViewRowEventArgs (emptyRow));
1510                                         mainTable.Rows.Add (emptyRow);
1511                                         if (dataBinding) {
1512                                                 emptyRow.DataBind ();
1513                                                 OnRowDataBound (new GridViewRowEventArgs (emptyRow));
1514                                         }
1515                                 }
1516                                 if (mainTable.Rows.Count == 0)
1517                                         table = null;
1518                                 return 0;
1519                         } else {
1520                                 GridViewRow footerRow = CreateRow (-1, -1, DataControlRowType.Footer, DataControlRowState.Normal);
1521                                 InitializeRow (footerRow, fields);
1522                                 OnRowCreated (new GridViewRowEventArgs (footerRow));
1523                                 mainTable.Rows.Add (footerRow);
1524                                 if (dataBinding) {
1525                                         footerRow.DataBind ();
1526                                         OnRowDataBound (new GridViewRowEventArgs (footerRow));
1527                                 }
1528
1529                                 if (createPager && (PagerSettings.Position == PagerPosition.Bottom || PagerSettings.Position == PagerPosition.TopAndBottom)) {
1530                                         bottomPagerRow = CreatePagerRow (fieldCount, dataSource);
1531                                         OnRowCreated (new GridViewRowEventArgs (bottomPagerRow));
1532                                         mainTable.Rows.Add (bottomPagerRow);
1533                                         if (dataBinding) {
1534                                                 bottomPagerRow.DataBind ();
1535                                                 OnRowDataBound (new GridViewRowEventArgs (bottomPagerRow));
1536                                         }
1537                                         if (PageCount == 1)
1538                                                 bottomPagerRow.Visible = false;
1539                                 }
1540                         }
1541
1542                         rows = new GridViewRowCollection (list);
1543
1544                         if (!dataBinding)
1545                                 return -1;
1546
1547                         if (AllowPaging)
1548                                 return dataSource.DataSourceCount;
1549                         else
1550                                 return list.Count;
1551                 }
1552
1553                 Table ContainedTable  {
1554                         get {
1555                                 if (table == null) {
1556                                         table = CreateChildTable ();
1557                                         Controls.Add (table);
1558                                 }
1559                                 
1560                                 return table;
1561                         }
1562                 }
1563
1564                 protected override Style CreateControlStyle ()
1565                 {
1566                         TableStyle style = new TableStyle (ViewState);
1567                         style.GridLines = GridLines.Both;
1568                         style.CellSpacing = 0;
1569                         return style;
1570                 }
1571                 
1572                 DataControlRowState GetRowState (int index)
1573                 {
1574                         DataControlRowState rstate = (index % 2) == 0 ? DataControlRowState.Normal : DataControlRowState.Alternate;
1575                         if (index == SelectedIndex)
1576                                 rstate |= DataControlRowState.Selected;
1577                         if (index == EditIndex)
1578                                 rstate |= DataControlRowState.Edit;
1579                         return rstate;
1580                 }
1581                 
1582                 GridViewRow CreatePagerRow (int fieldCount, PagedDataSource dataSource)
1583                 {
1584                         GridViewRow row = CreateRow (-1, -1, DataControlRowType.Pager, DataControlRowState.Normal);
1585                         InitializePager (row, fieldCount, dataSource);
1586                         return row;
1587                 }
1588                 
1589                 protected virtual void InitializePager (GridViewRow row, int columnSpan, PagedDataSource dataSource)
1590                 {
1591                         TableCell cell = new TableCell ();
1592                         if (columnSpan > 1)
1593                                 cell.ColumnSpan = columnSpan;
1594                         
1595                         if (pagerTemplate != null)
1596                                 pagerTemplate.InstantiateIn (cell);
1597                         else
1598                                 cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount));
1599                         
1600                         row.Cells.Add (cell);
1601                 }
1602                 
1603                 GridViewRow CreateEmptyrRow (int fieldCount)
1604                 {
1605                         if (emptyDataTemplate == null && String.IsNullOrEmpty (EmptyDataText))
1606                                 return null;
1607
1608                         GridViewRow row = CreateRow (-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
1609                         TableCell cell = new TableCell ();
1610                         cell.ColumnSpan = fieldCount;
1611                         
1612                         if (emptyDataTemplate != null)
1613                                 emptyDataTemplate.InstantiateIn (cell);
1614                         else
1615                                 cell.Text = EmptyDataText;
1616                         
1617                         row.Cells.Add (cell);
1618                         return row;
1619                 }
1620                 
1621                 protected virtual void InitializeRow (GridViewRow row, DataControlField[] fields)
1622                 {
1623                         DataControlCellType ctype;
1624                         bool accessibleHeader = false;
1625
1626                         switch (row.RowType) {
1627                                 case DataControlRowType.Header:
1628                                         ctype = DataControlCellType.Header; 
1629                                         accessibleHeader = UseAccessibleHeader;
1630                                         break;
1631                                 case DataControlRowType.Footer:
1632                                         ctype = DataControlCellType.Footer;
1633                                         break;
1634                                 default:
1635                                         ctype = DataControlCellType.DataCell;
1636                                         break;
1637                         }
1638                         
1639                         for (int n=0; n<fields.Length; n++) {
1640                                 DataControlField field = fields [n];                            
1641                                 DataControlFieldCell cell;
1642
1643                                 if (((field is BoundField) && ((BoundField)field).DataField == RowHeaderColumn) || accessibleHeader)
1644                                         cell = new DataControlFieldHeaderCell (field, accessibleHeader ? TableHeaderScope.Column : TableHeaderScope.Row);
1645                                 else
1646                                         cell = new DataControlFieldCell (field);
1647                                 row.Cells.Add (cell);
1648                                 field.InitializeCell (cell, ctype, row.RowState, row.RowIndex);
1649                         }
1650                 }
1651                 
1652                 void LoadAndCacheProperties (string[] names, object dataItem, ref PropertyDescriptor[] cache)
1653                 {
1654                         if (cache != null)
1655                                 return;
1656
1657                         PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem);
1658                         int len = names != null ? names.Length : 0;
1659                         cache = new PropertyDescriptor [len];
1660                         for (int n = 0; n < len; n++) {
1661                                 string propName = names [n];
1662                                 PropertyDescriptor p = props.Find (propName, true);
1663                                 if (p == null)
1664                                         throw new InvalidOperationException ("Property '" + propName + "' not found in object of type " + dataItem.GetType ());
1665                                 cache [n] = p;
1666                         }
1667                 }
1668
1669                 IOrderedDictionary CreateDictionaryFromProperties (PropertyDescriptor[] cache, object dataItem)
1670                 {
1671                         OrderedDictionary dic = new OrderedDictionary ();
1672                         foreach (PropertyDescriptor p in cache)
1673                                 dic [p.Name] = p.GetValue (dataItem);
1674                         return dic;
1675                 }
1676                 
1677                 IOrderedDictionary CreateRowDataKey (GridViewRow row)
1678                 {
1679                         object dataItem = row.DataItem;
1680                         LoadAndCacheProperties (DataKeyNames, dataItem, ref cachedKeyProperties);
1681                         return CreateDictionaryFromProperties (cachedKeyProperties, dataItem);
1682                 }
1683                 IOrderedDictionary CreateRowSuffixDataKey (GridViewRow row)
1684                 {
1685                         object dataItem = row.DataItem;
1686                         LoadAndCacheProperties (ClientIDRowSuffix, dataItem, ref cachedSuffixKeyProperties);
1687                         return CreateDictionaryFromProperties (cachedSuffixKeyProperties, dataItem);
1688                 }
1689                 IOrderedDictionary GetRowValues (GridViewRow row, bool includeReadOnlyFields, bool includePrimaryKey)
1690                 {
1691                         OrderedDictionary dic = new OrderedDictionary ();
1692                         ExtractRowValues (dic, row, includeReadOnlyFields, includePrimaryKey);
1693                         return dic;
1694                 }
1695                 
1696                 protected virtual void ExtractRowValues (IOrderedDictionary fieldValues, GridViewRow row, bool includeReadOnlyFields, bool includePrimaryKey)
1697                 {
1698                         DataControlField field;
1699                         foreach (TableCell cell in row.Cells) {
1700                                 DataControlFieldCell c = cell as DataControlFieldCell;
1701                                 if (c == null)
1702                                         continue;
1703                                 
1704                                 field = c.ContainingField;
1705                                 if (field != null && !field.Visible)
1706                                         continue;
1707                                 
1708                                 c.ContainingField.ExtractValuesFromCell (fieldValues, c, row.RowState, includeReadOnlyFields);
1709                         }
1710                         if (!includePrimaryKey && DataKeyNames != null)
1711                                 foreach (string key in DataKeyNames)
1712                                         fieldValues.Remove (key);
1713                 }
1714                 
1715                 protected override HtmlTextWriterTag TagKey {
1716                         get {
1717                                 if (EnableSortingAndPagingCallbacks)
1718                                         return HtmlTextWriterTag.Div;
1719                                 else
1720                                         return HtmlTextWriterTag.Table;
1721                         }
1722                 }
1723                 
1724                 public sealed override void DataBind ()
1725                 {
1726                         DataKeyList.Clear ();
1727                         cachedKeyProperties = null;
1728                         base.DataBind ();
1729
1730                         keys = new DataKeyArray (DataKeyList);
1731                         
1732                         GridViewRow row = HeaderRow;
1733                         if (row != null)
1734                                 row.Visible = ShowHeader;
1735
1736                         row = FooterRow;
1737                         if (row != null)
1738                                 row.Visible = ShowFooter;
1739                 }
1740                 
1741                 protected internal override void PerformDataBinding (IEnumerable data)
1742                 {
1743                         base.PerformDataBinding (data);
1744                 }
1745
1746                 protected internal virtual void PrepareControlHierarchy ()
1747                 {
1748                         if (table == null)
1749                                 return;
1750
1751                         table.Caption = Caption;
1752                         table.CaptionAlign = CaptionAlign;
1753                         table.CopyBaseAttributes (this);
1754                         
1755                         foreach (GridViewRow row in table.Rows) {
1756                                 switch (row.RowType) {
1757                                         case DataControlRowType.Header:
1758                                                 if (headerStyle != null && !headerStyle.IsEmpty)
1759                                                         row.ControlStyle.MergeWith(headerStyle);
1760                                                 row.Visible = ShowHeader;
1761                                                 break;
1762                                         case DataControlRowType.Footer:
1763                                                 if (footerStyle != null && !footerStyle.IsEmpty)
1764                                                         row.ControlStyle.MergeWith (footerStyle);
1765                                                 row.Visible = ShowFooter;
1766                                                 break;
1767                                         case DataControlRowType.Pager:
1768                                                 if (pagerStyle != null && !pagerStyle.IsEmpty)
1769                                                         row.ControlStyle.MergeWith (pagerStyle);
1770                                                 break;
1771                                         case DataControlRowType.EmptyDataRow:
1772                                                 if (emptyDataRowStyle != null && !emptyDataRowStyle.IsEmpty)
1773                                                         row.ControlStyle.MergeWith (emptyDataRowStyle);
1774                                                 break;
1775                                         case DataControlRowType.DataRow:
1776                                                 if ((row.RowState & DataControlRowState.Edit) != 0 && editRowStyle != null && !editRowStyle.IsEmpty)
1777                                                         row.ControlStyle.MergeWith (editRowStyle);
1778                                                 if ((row.RowState & DataControlRowState.Selected) != 0 && selectedRowStyle != null && !selectedRowStyle.IsEmpty)
1779                                                         row.ControlStyle.MergeWith (selectedRowStyle);
1780                                                 if ((row.RowState & DataControlRowState.Alternate) != 0 && alternatingRowStyle != null && !alternatingRowStyle.IsEmpty)
1781                                                         row.ControlStyle.MergeWith (alternatingRowStyle);
1782                                                 if (rowStyle != null && !rowStyle.IsEmpty)
1783                                                         row.ControlStyle.MergeWith (rowStyle);
1784                                                 break;
1785                                         default:
1786                                                 break;
1787                                 }
1788                                 string sortExpression = SortExpression;
1789                                 bool haveSorting = !String.IsNullOrEmpty (sortExpression);
1790                                 foreach (TableCell cell in row.Cells) {
1791                                         DataControlFieldCell fcell = cell as DataControlFieldCell;
1792                                         if (fcell != null) {
1793                                                 DataControlField field = fcell.ContainingField;
1794                                                 if (field == null)
1795                                                         continue;
1796                                                 if (!field.Visible) {
1797                                                         cell.Visible = false;
1798                                                         continue;
1799                                                 }
1800                                                 
1801                                                 switch (row.RowType) {
1802                                                         case DataControlRowType.Header:
1803                                                                 if (field.HeaderStyleCreated && !field.HeaderStyle.IsEmpty)
1804                                                                         cell.ControlStyle.MergeWith (field.HeaderStyle);
1805                                                                 if (haveSorting)
1806                                                                         MergeWithSortingStyle (sortExpression, sortedAscendingHeaderStyle, sortedDescendingHeaderStyle, field, cell);
1807                                                                 break;
1808                                                         case DataControlRowType.Footer:
1809                                                                 if (field.FooterStyleCreated && !field.FooterStyle.IsEmpty)
1810                                                                         cell.ControlStyle.MergeWith (field.FooterStyle);
1811                                                                 break;
1812                                                         default:
1813                                                                 if (field.ControlStyleCreated && !field.ControlStyle.IsEmpty) {
1814                                                                         foreach (Control c in cell.Controls) {
1815                                                                                 WebControl wc = c as WebControl;
1816                                                                                 if (wc != null)
1817                                                                                         wc.ControlStyle.MergeWith (field.ControlStyle);
1818                                                                         }
1819                                                                 }
1820                                                                 if (field.ItemStyleCreated && !field.ItemStyle.IsEmpty)
1821                                                                         cell.ControlStyle.MergeWith (field.ItemStyle);
1822                                                                 if (haveSorting)
1823                                                                         MergeWithSortingStyle (sortExpression, sortedAscendingCellStyle, sortedDescendingCellStyle, field, cell);
1824                                                                 break;
1825                                                 }
1826                                         }
1827                                 }
1828                         }
1829                 }
1830                 void MergeWithSortingStyle (string sortExpression, TableItemStyle ascending, TableItemStyle descending, DataControlField field, TableCell cell)
1831                 {
1832                         if (String.Compare (field.SortExpression, sortExpression, StringComparison.OrdinalIgnoreCase) != 0)
1833                                 return;
1834
1835                         cell.ControlStyle.MergeWith (SortDirection == SortDirection.Ascending ? ascending : descending);
1836                 }
1837                 protected internal override void OnInit (EventArgs e)
1838                 {
1839                         Page page = Page;
1840                         if (page != null)
1841                                 page.RegisterRequiresControlState (this);
1842                         base.OnInit (e);
1843                 }
1844                 
1845                 void OnFieldsChanged (object sender, EventArgs args)
1846                 {
1847                         RequireBinding ();
1848                 }
1849                 
1850                 protected override void OnDataPropertyChanged ()
1851                 {
1852                         base.OnDataPropertyChanged ();
1853                         RequireBinding ();
1854                 }
1855                 
1856                 protected override void OnDataSourceViewChanged (object sender, EventArgs e)
1857                 {
1858                         base.OnDataSourceViewChanged (sender, e);
1859                         RequireBinding ();
1860                 }
1861                 
1862                 protected override bool OnBubbleEvent (object source, EventArgs e)
1863                 {
1864                         GridViewCommandEventArgs args = e as GridViewCommandEventArgs;
1865                         if (args != null) {
1866                                 bool causesValidation = false;
1867                                 IButtonControl button = args.CommandSource as IButtonControl;
1868                                 if (button != null && button.CausesValidation) {
1869                                         Page.Validate (button.ValidationGroup);
1870                                         causesValidation = true;
1871                                 }
1872                                 OnRowCommand (args);
1873                                 string param = args.CommandArgument as string;
1874                                 if (param == null || param.Length == 0) {
1875                                         GridViewRow row = args.Row;
1876                                         if (row != null)
1877                                                 param = row.RowIndex.ToString();
1878                                 }
1879                                 ProcessEvent (args.CommandName, param, causesValidation);
1880                                 return true;
1881                         }
1882                         return base.OnBubbleEvent (source, e);
1883                 }
1884                 
1885                 void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
1886                 {
1887                         ValidateEvent (UniqueID, eventArgument);
1888                         RaisePostBackEvent (eventArgument);
1889                 }
1890
1891                 // This is prolly obsolete
1892                 protected virtual void RaisePostBackEvent (string eventArgument)
1893                 {
1894                         GridViewCommandEventArgs args;
1895                         int i = eventArgument.IndexOf ('$');
1896                         if (i != -1)
1897                                 args = new GridViewCommandEventArgs (this, new CommandEventArgs (eventArgument.Substring (0, i), eventArgument.Substring (i + 1)));
1898                         else
1899                                 args = new GridViewCommandEventArgs (this, new CommandEventArgs (eventArgument, null));
1900
1901                         OnRowCommand (args);
1902                         ProcessEvent (args.CommandName, (string) args.CommandArgument, false);
1903                 }
1904
1905                 void ProcessEvent (string eventName, string param, bool causesValidation)
1906                 {
1907                         switch (eventName) {
1908                                 case DataControlCommands.PageCommandName:
1909                                         int newIndex = -1;
1910                                         switch (param) {
1911                                                 case DataControlCommands.FirstPageCommandArgument:
1912                                                         newIndex = 0;
1913                                                         break;
1914                                                 case DataControlCommands.LastPageCommandArgument:
1915                                                         newIndex = PageCount - 1;
1916                                                         break;
1917                                                 case DataControlCommands.NextPageCommandArgument:
1918                                                         newIndex = PageIndex + 1;
1919                                                         break;
1920                                                 case DataControlCommands.PreviousPageCommandArgument:
1921                                                         newIndex = PageIndex - 1;
1922                                                         break;
1923                                                 default:
1924                                                         int paramIndex = 0;
1925                                                         int.TryParse (param, out paramIndex);
1926                                                         newIndex = paramIndex - 1;
1927                                                         break;
1928                                         }
1929                                         SetPageIndex (newIndex);
1930                                         break;
1931                                         
1932                                 case DataControlCommands.FirstPageCommandArgument:
1933                                         SetPageIndex (0);
1934                                         break;
1935
1936                                 case DataControlCommands.LastPageCommandArgument:
1937                                         SetPageIndex (PageCount - 1);
1938                                         break;
1939                                         
1940                                 case DataControlCommands.NextPageCommandArgument:
1941                                         if (PageIndex < PageCount - 1)
1942                                                 SetPageIndex (PageIndex + 1);
1943                                         break;
1944
1945                                 case DataControlCommands.PreviousPageCommandArgument:
1946                                         if (PageIndex > 0)
1947                                                 SetPageIndex (PageIndex - 1);
1948                                         break;
1949                                         
1950                                 case DataControlCommands.SelectCommandName:
1951                                         SelectRow (int.Parse (param));
1952                                         break;
1953                                         
1954                                 case DataControlCommands.EditCommandName:
1955                                         SetEditRow (int.Parse (param));
1956                                         break;
1957                                         
1958                                 case DataControlCommands.UpdateCommandName:
1959                                         int editIndex = int.Parse (param);
1960                                         UpdateRow (Rows [editIndex], editIndex, causesValidation);
1961                                         break;
1962                                         
1963                                 case DataControlCommands.CancelCommandName:
1964                                         CancelEdit ();
1965                                         break;
1966                                         
1967                                 case DataControlCommands.DeleteCommandName:
1968                                         DeleteRow (int.Parse (param));
1969                                         break;
1970                                         
1971                                 case DataControlCommands.SortCommandName:
1972                                         Sort (param);
1973                                         break;
1974                         }
1975                 }
1976                 
1977                 void Sort (string newSortExpression)
1978                 {
1979                         SortDirection newDirection = SortDirection.Ascending;
1980                         if (sortExpression == newSortExpression && sortDirection == SortDirection.Ascending)
1981                                 newDirection = SortDirection.Descending;
1982
1983                         Sort (newSortExpression, newDirection);
1984                 }
1985                 
1986                 public virtual void Sort (string newSortExpression, SortDirection newSortDirection)
1987                 {
1988                         GridViewSortEventArgs args = new GridViewSortEventArgs (newSortExpression, newSortDirection);
1989                         OnSorting (args);
1990                         if (args.Cancel)
1991                                 return;
1992                         
1993                         if (IsBoundUsingDataSourceID) {
1994                                 EditIndex = -1;
1995                                 PageIndex = 0;
1996                                 SortExpression = args.SortExpression;
1997                                 SortDirection = args.SortDirection;
1998                         }
1999                         
2000                         OnSorted (EventArgs.Empty);
2001                 }
2002                 public
2003                 void SelectRow (int index)
2004                 {
2005                         GridViewSelectEventArgs args = new GridViewSelectEventArgs (index);
2006                         OnSelectedIndexChanging (args);
2007                         if (!args.Cancel) {
2008                                 RequireBinding ();
2009                                 SelectedIndex = args.NewSelectedIndex;
2010                                 OnSelectedIndexChanged (EventArgs.Empty);
2011                         }
2012                 }
2013                 public
2014                 void SetPageIndex (int newIndex)
2015                 {
2016                         GridViewPageEventArgs args = new GridViewPageEventArgs (newIndex);
2017                         OnPageIndexChanging (args);
2018                         
2019                         if (args.Cancel || !IsBoundUsingDataSourceID)
2020                                 return;
2021                         
2022                         EndRowEdit ();
2023                         PageIndex = args.NewPageIndex;
2024                         OnPageIndexChanged (EventArgs.Empty);
2025                 }
2026                 public
2027                 void SetEditRow (int index)
2028                 {
2029                         GridViewEditEventArgs args = new GridViewEditEventArgs (index);
2030                         OnRowEditing (args);
2031                         
2032                         if (args.Cancel || !IsBoundUsingDataSourceID)
2033                                 return;
2034                         
2035                         EditIndex = args.NewEditIndex;
2036                 }
2037                 
2038                 void CancelEdit ()
2039                 {
2040                         GridViewCancelEditEventArgs args = new GridViewCancelEditEventArgs (EditIndex);
2041                         OnRowCancelingEdit (args);
2042                         
2043                         if (args.Cancel || !IsBoundUsingDataSourceID)
2044                                 return;
2045
2046                         EndRowEdit ();
2047                 }
2048
2049                 [MonoTODO ("Support two-way binding expressions")]
2050                 public virtual void UpdateRow (int rowIndex, bool causesValidation)
2051                 {
2052                         if (rowIndex != EditIndex)
2053                                 throw new NotSupportedException ();
2054                         
2055                         GridViewRow row = Rows [rowIndex];
2056                         UpdateRow (row, rowIndex, causesValidation);
2057                 }
2058
2059                 void UpdateRow (GridViewRow row, int rowIndex, bool causesValidation)
2060                 {
2061                         if (causesValidation && Page != null && !Page.IsValid)
2062                                 return;
2063
2064                         currentEditOldValues = CopyOrderedDictionary (OldEditValues.Values);
2065                         currentEditRowKeys = CopyOrderedDictionary (DataKeys [rowIndex].Values);
2066                         currentEditNewValues = GetRowValues (row, false, false);
2067                         
2068                         GridViewUpdateEventArgs args = new GridViewUpdateEventArgs (rowIndex, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
2069                         OnRowUpdating (args);
2070                         
2071                         if (args.Cancel || !IsBoundUsingDataSourceID)
2072                                 return;
2073                         
2074                         DataSourceView view = GetData ();
2075                         if (view == null)
2076                                 throw new HttpException ("The DataSourceView associated to data bound control was null");
2077                         view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback));
2078                 }
2079
2080                 static IOrderedDictionary CopyOrderedDictionary (IOrderedDictionary sourceDic)
2081                 {
2082                         OrderedDictionary copyDic = new OrderedDictionary ();
2083                         foreach (object key in sourceDic.Keys)
2084                                 copyDic.Add (key, sourceDic [key]);
2085                         return copyDic;
2086                 }
2087
2088                 bool UpdateCallback (int recordsAffected, Exception exception)
2089                 {
2090                         GridViewUpdatedEventArgs dargs = new GridViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
2091                         OnRowUpdated (dargs);
2092
2093                         if (!dargs.KeepInEditMode)              
2094                                 EndRowEdit ();
2095
2096                         return dargs.ExceptionHandled;
2097                 }
2098                 
2099                 public virtual void DeleteRow (int rowIndex)
2100                 {
2101                         GridViewRow row = Rows [rowIndex];
2102                         currentEditRowKeys = CopyOrderedDictionary (DataKeys [rowIndex].Values);
2103                         currentEditNewValues = GetRowValues (row, true, true);
2104                         
2105                         GridViewDeleteEventArgs args = new GridViewDeleteEventArgs (rowIndex, currentEditRowKeys, currentEditNewValues);
2106                         OnRowDeleting (args);
2107
2108                         if (args.Cancel || !IsBoundUsingDataSourceID)
2109                                 return;
2110                         
2111                         RequireBinding ();
2112                         DataSourceView view = GetData ();
2113                         if (view != null)
2114                                 view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
2115                         else {
2116                                 GridViewDeletedEventArgs dargs = new GridViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
2117                                 OnRowDeleted (dargs);
2118                         }
2119                 }
2120
2121                 bool DeleteCallback (int recordsAffected, Exception exception)
2122                 {
2123                         GridViewDeletedEventArgs dargs = new GridViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues);
2124                         OnRowDeleted (dargs);
2125                         return dargs.ExceptionHandled;
2126                 }
2127                 
2128                 void EndRowEdit ()
2129                 {
2130                         EditIndex = -1;
2131                         oldEditValues = new DataKey (new OrderedDictionary ());
2132                         currentEditRowKeys = null;
2133                         currentEditOldValues = null;
2134                         currentEditNewValues = null;
2135                 }
2136
2137                 protected internal override void LoadControlState (object ob)
2138                 {
2139                         if (ob == null)
2140                                 return;
2141                         object[] state = (object[]) ob;
2142                         base.LoadControlState (state[0]);
2143                         pageIndex = (int) state[1];
2144                         selectedIndex = (int) state[2];
2145                         editIndex = (int) state[3];
2146                         sortExpression = (string) state[4];
2147                         sortDirection = (SortDirection) state[5];
2148                         DataKeyNames = (string []) state [6];
2149                         if (state [7] != null)
2150                                 LoadDataKeyArrayState ((object []) state [7], out keys);
2151                         if (state [8] != null)
2152                                 ((IStateManager) OldEditValues).LoadViewState (state [8]);
2153                         pageCount = (int)state [9];
2154                         if (state [10] != null)
2155                                 ClientIDRowSuffix = (string[]) state [10];
2156                         if (state [11] != null)
2157                                 LoadDataKeyArrayState ((object []) state [11], out rowSuffixKeys);
2158                 }
2159                 
2160                 protected internal override object SaveControlState ()
2161                 {
2162                         if (EnableSortingAndPagingCallbacks) {
2163                                 Page page = Page;
2164                                 ClientScriptManager scriptManager = page != null ? page.ClientScript : null;
2165
2166                                 if (scriptManager != null) {
2167                                         scriptManager.RegisterHiddenField (ClientID + "_Page", PageIndex.ToString ());
2168                                         scriptManager.RegisterHiddenField (ClientID + "_SortExpression", SortExpression);
2169                                         scriptManager.RegisterHiddenField (ClientID + "_SortDirection", ((int)SortDirection).ToString());
2170                                 }
2171                         }
2172
2173                         object bstate = base.SaveControlState ();
2174                         return new object [] {
2175                                 bstate, 
2176                                 pageIndex, 
2177                                 selectedIndex, 
2178                                 editIndex, 
2179                                 sortExpression, 
2180                                 sortDirection, 
2181                                 DataKeyNames,
2182                                 SaveDataKeyArrayState (keys),
2183                                 (oldEditValues == null ? null : ((IStateManager)oldEditValues).SaveViewState ()),
2184                                 pageCount,
2185                                 ClientIDRowSuffix,
2186                                 SaveDataKeyArrayState (rowSuffixKeys)
2187                         };
2188                 }
2189
2190                 object [] SaveDataKeyArrayState (DataKeyArray keys)
2191                 {
2192                         if (keys == null)
2193                                 return null;
2194
2195                         object [] state = new object [keys.Count];
2196                         for (int i = 0; i < keys.Count; i++)
2197                                 state [i] = ((IStateManager) keys [i]).SaveViewState ();
2198                         return state;
2199                 }
2200
2201                 void LoadDataKeyArrayState (object [] state, out DataKeyArray keys)
2202                 {
2203                         List <DataKey> dataKeyList = DataKeyList;
2204                         string[] dataKeyNames = DataKeyNames;
2205                         int dataKeyNamesLen = dataKeyNames.Length;
2206                         
2207                         for (int i = 0; i < state.Length; i++) {
2208                                 DataKey dataKey = new DataKey (new OrderedDictionary (dataKeyNamesLen), dataKeyNames);
2209                                 ((IStateManager) dataKey).LoadViewState (state [i]);
2210                                 dataKeyList.Add (dataKey);
2211                         }
2212                         keys = new DataKeyArray (dataKeyList);
2213                 }
2214
2215                 protected override void TrackViewState ()
2216                 {
2217                         base.TrackViewState();
2218                         if (columns != null)
2219                                 ((IStateManager)columns).TrackViewState();
2220                         if (pagerSettings != null)
2221                                 ((IStateManager)pagerSettings).TrackViewState();
2222                         if (alternatingRowStyle != null)
2223                                 ((IStateManager)alternatingRowStyle).TrackViewState();
2224                         if (footerStyle != null)
2225                                 ((IStateManager)footerStyle).TrackViewState();
2226                         if (headerStyle != null)
2227                                 ((IStateManager)headerStyle).TrackViewState();
2228                         if (pagerStyle != null)
2229                                 ((IStateManager)pagerStyle).TrackViewState();
2230                         if (rowStyle != null)
2231                                 ((IStateManager)rowStyle).TrackViewState();
2232                         if (selectedRowStyle != null)
2233                                 ((IStateManager)selectedRowStyle).TrackViewState();
2234                         if (editRowStyle != null)
2235                                 ((IStateManager)editRowStyle).TrackViewState();
2236                         if (emptyDataRowStyle != null)
2237                                 ((IStateManager)emptyDataRowStyle).TrackViewState();
2238                         if (sortedAscendingCellStyle != null)
2239                                 ((IStateManager)sortedAscendingCellStyle).TrackViewState ();
2240                         
2241                         if (sortedAscendingHeaderStyle != null)
2242                                 ((IStateManager)sortedAscendingHeaderStyle).TrackViewState ();
2243                         
2244                         if (sortedDescendingCellStyle != null)
2245                                 ((IStateManager)sortedDescendingCellStyle).TrackViewState ();
2246                         
2247                         if (sortedDescendingHeaderStyle != null)
2248                                 ((IStateManager)sortedDescendingHeaderStyle).TrackViewState ();
2249                         if (rowSuffixKeys != null)
2250                                 ((IStateManager) rowSuffixKeys).TrackViewState ();
2251                         if (keys != null)
2252                                 ((IStateManager)keys).TrackViewState();
2253                         if (autoFieldProperties != null) {
2254                                 foreach (IStateManager sm in autoFieldProperties)
2255                                         sm.TrackViewState ();
2256                         }
2257                 }
2258
2259                 protected override object SaveViewState ()
2260                 {
2261                         object[] autoFieldsData = null;
2262                         
2263                         if (autoFieldProperties != null) {
2264                                 object[] data = new object [autoFieldProperties.Length];
2265                                 bool allNull = true;
2266                                 for (int n = 0; n < data.Length; n++) {
2267                                         data [n] = ((IStateManager)autoFieldProperties [n]).SaveViewState ();
2268                                         if (data [n] != null)
2269                                                 allNull = false;
2270                                 }
2271                                 if (!allNull)
2272                                         autoFieldsData = data;
2273                         }
2274                         
2275                         object[] states = {
2276                                 base.SaveViewState(), // 0
2277                                 (columns == null ? null : ((IStateManager)columns).SaveViewState()), // 1
2278                                 (pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState()), // 2
2279                                 (alternatingRowStyle == null ? null : ((IStateManager)alternatingRowStyle).SaveViewState()), // 3
2280                                 (footerStyle == null ? null : ((IStateManager)footerStyle).SaveViewState()), // 4
2281                                 (headerStyle == null ? null : ((IStateManager)headerStyle).SaveViewState()), // 5
2282                                 (pagerStyle == null ? null : ((IStateManager)pagerStyle).SaveViewState()), // 6
2283                                 (rowStyle == null ? null : ((IStateManager)rowStyle).SaveViewState()), // 7
2284                                 (selectedRowStyle == null ? null : ((IStateManager)selectedRowStyle).SaveViewState()), // 8
2285                                 (editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState()), // 9
2286                                 (emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).SaveViewState()), // 10
2287                                 autoFieldsData, // 11
2288                                 sortedAscendingCellStyle == null ? null : ((IStateManager)sortedAscendingCellStyle).SaveViewState (), // 12
2289                                 sortedAscendingHeaderStyle == null ? null : ((IStateManager)sortedAscendingHeaderStyle).SaveViewState (), // 13
2290                                 sortedDescendingCellStyle == null ? null : ((IStateManager)sortedDescendingCellStyle).SaveViewState (), // 14
2291                                 sortedDescendingHeaderStyle == null ? null : ((IStateManager)sortedDescendingHeaderStyle).SaveViewState () // 15
2292                         };
2293
2294                         for (int i = states.Length - 1; i >= 0; i--) {
2295                                 if (states [i] != null)
2296                                         return states;
2297                         }
2298
2299                         return null;
2300                 }
2301
2302                 protected override void LoadViewState (object savedState)
2303                 {
2304                         if (savedState == null) {
2305                                 base.LoadViewState (null);
2306                                 return;
2307                         }
2308
2309                         object [] states = (object []) savedState;
2310                         
2311                         if (states[11] != null) {
2312                                 object[] data = (object[]) states [11];
2313                                 autoFieldProperties = new AutoGeneratedFieldProperties [data.Length];
2314                                 for (int n=0; n<data.Length; n++) {
2315                                         IStateManager p = new AutoGeneratedFieldProperties ();
2316                                         p.TrackViewState ();
2317                                         p.LoadViewState (data [n]);
2318                                         autoFieldProperties [n] = (AutoGeneratedFieldProperties) p;
2319                                 }
2320                         }
2321
2322                         base.LoadViewState (states[0]);
2323                         
2324                         if (states[1] != null)
2325                                 ((IStateManager)Columns).LoadViewState (states[1]);
2326                         if (states[2] != null)
2327                                 ((IStateManager)PagerSettings).LoadViewState (states[2]);
2328                         if (states[3] != null)
2329                                 ((IStateManager)AlternatingRowStyle).LoadViewState (states[3]);
2330                         if (states[4] != null)
2331                                 ((IStateManager)FooterStyle).LoadViewState (states[4]);
2332                         if (states[5] != null)
2333                                 ((IStateManager)HeaderStyle).LoadViewState (states[5]);
2334                         if (states[6] != null)
2335                                 ((IStateManager)PagerStyle).LoadViewState (states[6]);
2336                         if (states[7] != null)
2337                                 ((IStateManager)RowStyle).LoadViewState (states[7]);
2338                         if (states[8] != null)
2339                                 ((IStateManager)SelectedRowStyle).LoadViewState (states[8]);
2340                         if (states[9] != null)
2341                                 ((IStateManager)EditRowStyle).LoadViewState (states[9]);
2342                         if (states[10] != null)
2343                                 ((IStateManager)EmptyDataRowStyle).LoadViewState (states[10]);
2344                         if (states [12] != null)
2345                                 ((IStateManager)sortedAscendingCellStyle).LoadViewState (states [12]);
2346                         if (states [13] != null)
2347                                 ((IStateManager)sortedAscendingHeaderStyle).LoadViewState (states [13]);
2348                         if (states [14] != null)
2349                                 ((IStateManager)sortedDescendingCellStyle).LoadViewState (states [14]);
2350                         if (states [15] != null)
2351                                 ((IStateManager)sortedDescendingHeaderStyle).LoadViewState (states [15]);
2352                 }
2353                 
2354                 void ICallbackEventHandler.RaiseCallbackEvent (string eventArgs)
2355                 {
2356                         RaiseCallbackEvent (eventArgs);
2357                 }
2358                 
2359                 protected virtual void RaiseCallbackEvent (string eventArgs)
2360                 {
2361                         string[] clientData = eventArgs.Split ('|');
2362                         PageIndex = int.Parse (clientData[0]);
2363                         SortExpression = HttpUtility.UrlDecode (clientData [1]);
2364                         SortDirection = (SortDirection) int.Parse (clientData [2]);
2365                         
2366                         RaisePostBackEvent (clientData[3]);
2367                         DataBind ();
2368                 }
2369                 
2370                 string ICallbackEventHandler.GetCallbackResult ()
2371                 {
2372                         return GetCallbackResult ();
2373                 }
2374
2375                 protected virtual string GetCallbackResult ()
2376                 {
2377                         PrepareControlHierarchy ();
2378                         
2379                         StringWriter sw = new StringWriter ();
2380                         sw.Write (PageIndex.ToString () + '|' + SortExpression + '|' + (int) SortDirection + '|');
2381
2382                         HtmlTextWriter writer = new HtmlTextWriter (sw);
2383                         RenderGrid (writer);
2384                         return sw.ToString ();
2385                 }
2386
2387                 string ICallbackContainer.GetCallbackScript (IButtonControl control, string argument)
2388                 {
2389                         return GetCallbackScript (control, argument);
2390                 }
2391                 
2392                 protected virtual string GetCallbackScript (IButtonControl control, string argument)
2393                 {
2394                         if (EnableSortingAndPagingCallbacks) {
2395                                 Page page = Page;
2396                                 if (page != null)
2397                                         page.ClientScript.RegisterForEventValidation (UniqueID, argument);
2398                                 return "javascript:GridView_ClientEvent (\"" + ClientID + "\",\"" + control.CommandName + "$" + control.CommandArgument + "\"); return false;";
2399                         } else
2400                                 return null;
2401                 }
2402                 
2403                 protected override void OnPagePreLoad (object sender, EventArgs e)
2404                 {
2405                         base.OnPagePreLoad (sender, e);
2406                         Page page = Page;
2407                         
2408                         if (page != null && page.IsPostBack && EnableSortingAndPagingCallbacks) {
2409                                 HttpRequest req = page.Request;
2410                                 int value;
2411                                 if (req != null) {
2412                                         if (int.TryParse (req.Form [ClientID + "_Page"], out value))
2413                                                 PageIndex = value;
2414
2415                                         if (int.TryParse (req.Form [ClientID + "_SortDirection"], out value))
2416                                                 SortDirection = (SortDirection) value;
2417                                         SortExpression = req.Form [ClientID + "_SortExpression"];
2418                                 }
2419                         }
2420                 }
2421
2422                 const string onPreRenderScript = @"var {0} = new Object ();
2423 {0}.pageIndex = {1};
2424 {0}.sortExp = {2};
2425 {0}.sortDir = {3};
2426 {0}.uid = {4};
2427 {0}.form = {5};
2428 ";
2429                 protected internal override void OnPreRender (EventArgs e)
2430                 {
2431                         base.OnPreRender (e);
2432
2433                         if (EnableSortingAndPagingCallbacks) {
2434                                 Page page = Page;
2435                                 ClientScriptManager scriptManager = page != null ? page.ClientScript : null;
2436                                 if (scriptManager != null) {
2437                                         if (!scriptManager.IsClientScriptIncludeRegistered (typeof(GridView), "GridView.js")) {
2438                                                 string url = scriptManager.GetWebResourceUrl (typeof(GridView), "GridView.js");
2439                                                 scriptManager.RegisterClientScriptInclude (typeof(GridView), "GridView.js", url);
2440                                         }
2441                                 
2442                                         string cgrid = ClientID + "_data";
2443                                         string script = String.Format (onPreRenderScript,
2444                                                                        cgrid,
2445                                                                        ClientScriptManager.GetScriptLiteral (PageIndex),
2446                                                                        ClientScriptManager.GetScriptLiteral (SortExpression == null ? String.Empty : SortExpression),
2447                                                                        ClientScriptManager.GetScriptLiteral ((int) SortDirection),
2448                                                                        ClientScriptManager.GetScriptLiteral (UniqueID),
2449                                                                        page.theForm);
2450                                 
2451                                         scriptManager.RegisterStartupScript (typeof(TreeView), this.UniqueID, script, true);
2452                                 
2453                                         // Make sure the basic script infrastructure is rendered
2454                                         scriptManager.GetCallbackEventReference (this, "null", String.Empty, "null");
2455                                         scriptManager.GetPostBackClientHyperlink (this, String.Empty);
2456                                 }
2457                         }
2458                 }
2459                 
2460                 protected internal override void Render (HtmlTextWriter writer)
2461                 {
2462                         PrepareControlHierarchy ();
2463                         if (EnableSortingAndPagingCallbacks)
2464                                 writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID + "_div");
2465                         writer.RenderBeginTag (HtmlTextWriterTag.Div);
2466
2467                         RenderGrid (writer);
2468
2469                         writer.RenderEndTag ();
2470                 }
2471                 
2472                 void RenderGrid (HtmlTextWriter writer)
2473                 {
2474                         if (table == null)
2475                                 return;
2476
2477                         table.Render (writer);
2478                 }
2479
2480                 PostBackOptions IPostBackContainer.GetPostBackOptions (IButtonControl control)
2481                 {
2482                         if (control == null)
2483                                 throw new ArgumentNullException ("control");
2484                         
2485                         if (control.CausesValidation)
2486                                 throw new InvalidOperationException ("A button that causes validation in GridView '" + ID + "' is attempting to use the container GridView as the post back target.  The button should either turn off validation or use itself as the post back container.");
2487                         
2488                         PostBackOptions options = new PostBackOptions (this);
2489                         options.Argument = control.CommandName + "$" + control.CommandArgument;
2490                         options.RequiresJavaScriptProtocol = true;
2491
2492                         return options;
2493                 }
2494         }
2495 }