Merge pull request #704 from jgagnon/master
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / DetailsView.cs
1 //
2 // System.Web.UI.WebControls.DetailsView.cs
3 //
4 // Authors:
5 //      Lluis Sanchez Gual (lluis@novell.com)
6 //
7 // (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.Specialized;
32 using System.ComponentModel;
33 using System.Web.UI;
34 using System.Security.Permissions;
35 using System.Text;
36 using System.IO;
37 using System.Reflection;
38
39 namespace System.Web.UI.WebControls
40 {
41         [SupportsEventValidation]
42         [ToolboxDataAttribute ("<{0}:DetailsView runat=\"server\" Width=\"125px\" Height=\"50px\"></{0}:DetailsView>")]
43         [DesignerAttribute ("System.Web.UI.Design.WebControls.DetailsViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
44         [ControlValuePropertyAttribute ("SelectedValue")]
45         [DefaultEventAttribute ("PageIndexChanging")]
46         [DataKeyProperty ("DataKey")]
47         [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
48         [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
49         public class DetailsView: CompositeDataBoundControl, ICallbackEventHandler, ICallbackContainer, IDataItemContainer, INamingContainer, IPostBackEventHandler, IPostBackContainer
50                 , IDataBoundItemControl, IDataBoundControl, IFieldControl
51         {
52                 object dataItem;
53                 
54                 Table table;
55                 DetailsViewRowCollection rows;
56                 DetailsViewRow headerRow;
57                 DetailsViewRow footerRow;
58                 DetailsViewRow bottomPagerRow;
59                 DetailsViewRow topPagerRow;
60                 
61                 IOrderedDictionary currentEditRowKeys;
62                 IOrderedDictionary currentEditNewValues;
63                 IOrderedDictionary currentEditOldValues;
64                 
65                 ITemplate pagerTemplate;
66                 ITemplate emptyDataTemplate;
67                 ITemplate headerTemplate;
68                 ITemplate footerTemplate;
69                 
70                 PropertyDescriptor[] cachedKeyProperties;
71                 readonly string[] emptyKeys = new string[0];
72                 readonly string unhandledEventExceptionMessage = "The DetailsView '{0}' fired event {1} which wasn't handled.";
73                 
74                 // View state
75                 DataControlFieldCollection columns;
76                 PagerSettings pagerSettings;
77                 
78                 TableItemStyle alternatingRowStyle;
79                 TableItemStyle editRowStyle;
80                 TableItemStyle insertRowStyle;
81                 TableItemStyle emptyDataRowStyle;
82                 TableItemStyle footerStyle;
83                 TableItemStyle headerStyle;
84                 TableItemStyle pagerStyle;
85                 TableItemStyle rowStyle;
86                 TableItemStyle commandRowStyle;
87                 TableItemStyle fieldHeaderStyle;
88                 
89                 IOrderedDictionary _keyTable;
90                 DataKey key;
91                 DataKey oldEditValues;
92                 AutoGeneratedFieldProperties[] autoFieldProperties;
93                 
94                 static readonly object PageIndexChangedEvent = new object();
95                 static readonly object PageIndexChangingEvent = new object();
96                 static readonly object ItemCommandEvent = new object();
97                 static readonly object ItemCreatedEvent = new object();
98                 static readonly object ItemDeletedEvent = new object();
99                 static readonly object ItemDeletingEvent = new object();
100                 static readonly object ItemInsertedEvent = new object();
101                 static readonly object ItemInsertingEvent = new object();
102                 static readonly object ModeChangingEvent = new object();
103                 static readonly object ModeChangedEvent = new object();
104                 static readonly object ItemUpdatedEvent = new object();
105                 static readonly object ItemUpdatingEvent = new object();
106                 
107                 // Control state
108                 int pageIndex;
109                 DetailsViewMode currentMode = DetailsViewMode.ReadOnly; 
110                 bool hasCurrentMode;
111                 int pageCount;
112                 
113                 public DetailsView ()
114                 {
115                         rows = new DetailsViewRowCollection (new ArrayList ());
116                 }
117                 
118                 public event EventHandler PageIndexChanged {
119                         add { Events.AddHandler (PageIndexChangedEvent, value); }
120                         remove { Events.RemoveHandler (PageIndexChangedEvent, value); }
121                 }
122                 
123                 public event DetailsViewPageEventHandler PageIndexChanging {
124                         add { Events.AddHandler (PageIndexChangingEvent, value); }
125                         remove { Events.RemoveHandler (PageIndexChangingEvent, value); }
126                 }
127                 
128                 public event DetailsViewCommandEventHandler ItemCommand {
129                         add { Events.AddHandler (ItemCommandEvent, value); }
130                         remove { Events.RemoveHandler (ItemCommandEvent, value); }
131                 }
132                 
133                 public event EventHandler ItemCreated {
134                         add { Events.AddHandler (ItemCreatedEvent, value); }
135                         remove { Events.RemoveHandler (ItemCreatedEvent, value); }
136                 }
137                 
138                 public event DetailsViewDeletedEventHandler ItemDeleted {
139                         add { Events.AddHandler (ItemDeletedEvent, value); }
140                         remove { Events.RemoveHandler (ItemDeletedEvent, value); }
141                 }
142                 
143                 public event DetailsViewDeleteEventHandler ItemDeleting {
144                         add { Events.AddHandler (ItemDeletingEvent, value); }
145                         remove { Events.RemoveHandler (ItemDeletingEvent, value); }
146                 }
147                 
148                 public event DetailsViewInsertedEventHandler ItemInserted {
149                         add { Events.AddHandler (ItemInsertedEvent, value); }
150                         remove { Events.RemoveHandler (ItemInsertedEvent, value); }
151                 }
152                 
153                 public event DetailsViewInsertEventHandler ItemInserting {
154                         add { Events.AddHandler (ItemInsertingEvent, value); }
155                         remove { Events.RemoveHandler (ItemInsertingEvent, value); }
156                 }
157                 
158                 public event DetailsViewModeEventHandler ModeChanging {
159                         add { Events.AddHandler (ModeChangingEvent, value); }
160                         remove { Events.RemoveHandler (ModeChangingEvent, value); }
161                 }
162                 
163                 public event EventHandler ModeChanged {
164                         add { Events.AddHandler (ModeChangedEvent, value); }
165                         remove { Events.RemoveHandler (ModeChangedEvent, value); }
166                 }
167                 
168                 public event DetailsViewUpdatedEventHandler ItemUpdated {
169                         add { Events.AddHandler (ItemUpdatedEvent, value); }
170                         remove { Events.RemoveHandler (ItemUpdatedEvent, value); }
171                 }
172                 
173                 public event DetailsViewUpdateEventHandler ItemUpdating {
174                         add { Events.AddHandler (ItemUpdatingEvent, value); }
175                         remove { Events.RemoveHandler (ItemUpdatingEvent, value); }
176                 }
177                 
178                 protected virtual void OnPageIndexChanged (EventArgs e)
179                 {
180                         if (Events != null) {
181                                 EventHandler eh = (EventHandler) Events [PageIndexChangedEvent];
182                                 if (eh != null) eh (this, e);
183                         }
184                 }
185                 
186                 protected virtual void OnPageIndexChanging (DetailsViewPageEventArgs e)
187                 {
188                         if (Events != null) {
189                                 DetailsViewPageEventHandler eh = (DetailsViewPageEventHandler) Events [PageIndexChangingEvent];
190                                 if (eh != null) {
191                                         eh (this, e);
192                                         return;
193                                 }
194                         }
195                         if (!IsBoundUsingDataSourceID)
196                                 throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "PageIndexChanging"));
197                 }
198                 
199                 protected virtual void OnItemCommand (DetailsViewCommandEventArgs e)
200                 {
201                         if (Events != null) {
202                                 DetailsViewCommandEventHandler eh = (DetailsViewCommandEventHandler) Events [ItemCommandEvent];
203                                 if (eh != null) eh (this, e);
204                         }
205                 }
206                 
207                 protected virtual void OnItemCreated (EventArgs e)
208                 {
209                         if (Events != null) {
210                                 EventHandler eh = (EventHandler) Events [ItemCreatedEvent];
211                                 if (eh != null) eh (this, e);
212                         }
213                 }
214                 
215                 protected virtual void OnItemDeleted (DetailsViewDeletedEventArgs e)
216                 {
217                         if (Events != null) {
218                                 DetailsViewDeletedEventHandler eh = (DetailsViewDeletedEventHandler) Events [ItemDeletedEvent];
219                                 if (eh != null) eh (this, e);
220                         }
221                 }
222                 
223                 protected virtual void OnItemInserted (DetailsViewInsertedEventArgs e)
224                 {
225                         if (Events != null) {
226                                 DetailsViewInsertedEventHandler eh = (DetailsViewInsertedEventHandler) Events [ItemInsertedEvent];
227                                 if (eh != null) eh (this, e);
228                         }
229                 }
230                 
231                 protected virtual void OnItemInserting (DetailsViewInsertEventArgs e)
232                 {
233                         if (Events != null) {
234                                 DetailsViewInsertEventHandler eh = (DetailsViewInsertEventHandler) Events [ItemInsertingEvent];
235                                 if (eh != null) {
236                                         eh (this, e);
237                                         return;
238                                 }
239                         }
240                         if (!IsBoundUsingDataSourceID)
241                                 throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ItemInserting"));
242                 }
243                 
244                 protected virtual void OnItemDeleting (DetailsViewDeleteEventArgs e)
245                 {
246                         if (Events != null) {
247                                 DetailsViewDeleteEventHandler eh = (DetailsViewDeleteEventHandler) Events [ItemDeletingEvent];
248                                 if (eh != null) {
249                                         eh (this, e);
250                                         return;
251                                 }
252                         }
253                         if (!IsBoundUsingDataSourceID)
254                                 throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ItemDeleting"));
255                 }
256                 
257                 protected virtual void OnModeChanged (EventArgs e)
258                 {
259                         if (Events != null) {
260                                 EventHandler eh = (EventHandler) Events [ModeChangedEvent];
261                                 if (eh != null) eh (this, e);
262                         }
263                 }
264                 
265                 protected virtual void OnModeChanging (DetailsViewModeEventArgs e)
266                 {
267                         if (Events != null) {
268                                 DetailsViewModeEventHandler eh = (DetailsViewModeEventHandler) Events [ModeChangingEvent];
269                                 if (eh != null) {
270                                         eh (this, e);
271                                         return;
272                                 }
273                         }
274                         if (!IsBoundUsingDataSourceID)
275                                 throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ModeChanging"));
276                 }
277                 
278                 protected virtual void OnItemUpdated (DetailsViewUpdatedEventArgs e)
279                 {
280                         if (Events != null) {
281                                 DetailsViewUpdatedEventHandler eh = (DetailsViewUpdatedEventHandler) Events [ItemUpdatedEvent];
282                                 if (eh != null) eh (this, e);
283                         }
284                 }
285                 
286                 protected virtual void OnItemUpdating (DetailsViewUpdateEventArgs e)
287                 {
288                         if (Events != null) {
289                                 DetailsViewUpdateEventHandler eh = (DetailsViewUpdateEventHandler) Events [ItemUpdatingEvent];
290                                 if (eh != null) {
291                                         eh (this, e);
292                                         return;
293                                 }
294                         }
295                         if (!IsBoundUsingDataSourceID)
296                                 throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ItemUpdating"));
297                 }
298                 
299                 DataBoundControlMode IDataBoundItemControl.Mode {
300                         get {
301                                 switch (CurrentMode) {
302                                         case DetailsViewMode.ReadOnly:
303                                                 return DataBoundControlMode.ReadOnly;
304
305                                         case DetailsViewMode.Edit:
306                                                 return DataBoundControlMode.Edit;
307
308                                         case DetailsViewMode.Insert:
309                                                 return DataBoundControlMode.Insert;
310
311                                         default:
312                                                 throw new InvalidOperationException (String.Format ("Unsupported CurrentMode value '{0}'", CurrentMode));
313                                 }
314                         }
315                 }
316
317                 IDataSource IDataBoundControl.DataSourceObject {
318                         get { return base.DataSourceObject; }
319                 }
320
321                 IAutoFieldGenerator IFieldControl.FieldsGenerator {
322                         get {
323                                 throw new NotImplementedException ();
324                         }
325                         
326                         set {
327                                 throw new NotImplementedException ();
328                         }
329                 }
330                 [WebCategoryAttribute ("Paging")]
331                 [DefaultValueAttribute (false)]
332                 public virtual bool AllowPaging {
333                         get {
334                                 object ob = ViewState ["AllowPaging"];
335                                 if (ob != null)
336                                         return (bool) ob;
337                                 return false;
338                         }
339                         set {
340                                 ViewState ["AllowPaging"] = value;
341                                 RequireBinding ();
342                         }
343                 }
344                 
345                 [DefaultValueAttribute (null)]
346                 [WebCategoryAttribute ("Styles")]
347                 [PersistenceMode (PersistenceMode.InnerProperty)]
348                 [NotifyParentProperty (true)]
349                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
350                 public TableItemStyle AlternatingRowStyle {
351                         get {
352                                 if (alternatingRowStyle == null) {
353                                         alternatingRowStyle = new TableItemStyle ();
354                                         if (IsTrackingViewState)
355                                                 alternatingRowStyle.TrackViewState();
356                                 }
357                                 return alternatingRowStyle;
358                         }
359                 }
360
361                 [WebCategoryAttribute ("Behavior")]
362                 [DefaultValueAttribute (false)]
363                 public virtual bool AutoGenerateEditButton {
364                         get {
365                                 object ob = ViewState ["AutoGenerateEditButton"];
366                                 if (ob != null)
367                                         return (bool) ob;
368                                 return false;
369                         }
370                         set {
371                                 ViewState ["AutoGenerateEditButton"] = value;
372                                 RequireBinding ();
373                         }
374                 }
375
376                 [WebCategoryAttribute ("Behavior")]
377                 [DefaultValueAttribute (false)]
378                 public virtual bool AutoGenerateDeleteButton {
379                         get {
380                                 object ob = ViewState ["AutoGenerateDeleteButton"];
381                                 if (ob != null)
382                                         return (bool) ob;
383                                 return false;
384                         }
385                         set {
386                                 ViewState ["AutoGenerateDeleteButton"] = value;
387                                 RequireBinding ();
388                         }
389                 }
390
391                 [WebCategoryAttribute ("Behavior")]
392                 [DefaultValueAttribute (false)]
393                 public virtual bool AutoGenerateInsertButton {
394                         get {
395                                 object ob = ViewState ["AutoGenerateInsertButton"];
396                                 if (ob != null)
397                                         return (bool) ob;
398                                 return false;
399                         }
400                         set {
401                                 ViewState ["AutoGenerateInsertButton"] = value;
402                                 RequireBinding ();
403                         }
404                 }
405
406                 [WebCategoryAttribute ("Behavior")]
407                 [DefaultValueAttribute (true)]
408                 public virtual bool AutoGenerateRows {
409                         get {
410                                 object ob = ViewState ["AutoGenerateRows"];
411                                 if (ob != null)
412                                         return (bool) ob;
413                                 return true;
414                         }
415                         set {
416                                 ViewState ["AutoGenerateRows"] = value;
417                                 RequireBinding ();
418                         }
419                 }
420                 
421                 [UrlPropertyAttribute]
422                 [WebCategoryAttribute ("Appearance")]
423                 [DefaultValueAttribute ("")]
424                 [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
425                 public virtual string BackImageUrl {
426                         get {
427                                 if (ControlStyleCreated)
428                                         return ((TableStyle) ControlStyle).BackImageUrl;
429                                 return String.Empty;
430                         }
431                         set {
432                                 ((TableStyle) ControlStyle).BackImageUrl = value;
433                         }
434                 }
435
436                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
437                 [BrowsableAttribute (false)]
438                 public virtual DetailsViewRow BottomPagerRow {
439                         get {
440                                 EnsureChildControls ();
441                                 return bottomPagerRow;
442                         }
443                 }
444         
445                 [WebCategoryAttribute ("Accessibility")]
446                 [DefaultValueAttribute ("")]
447                 [LocalizableAttribute (true)]
448                 public virtual string Caption {
449                         get {
450                                 object ob = ViewState ["Caption"];
451                                 if (ob != null)
452                                         return (string) ob;
453                                 return String.Empty;
454                         }
455                         set {
456                                 ViewState ["Caption"] = value;
457                                 RequireBinding ();
458                         }
459                 }
460                 
461                 [WebCategoryAttribute ("Accessibility")]
462                 [DefaultValueAttribute (TableCaptionAlign.NotSet)]
463                 public virtual TableCaptionAlign CaptionAlign {
464                         get {
465                                 object o = ViewState ["CaptionAlign"];
466                                 if(o != null)
467                                         return (TableCaptionAlign) o;
468                                 return TableCaptionAlign.NotSet;
469                         }
470                         set {
471                                 ViewState ["CaptionAlign"] = value;
472                                 RequireBinding ();
473                         }
474                 }
475
476                 [WebCategoryAttribute ("Layout")]
477                 [DefaultValueAttribute (-1)]
478                 public virtual int CellPadding {
479                         get {
480                                 if (ControlStyleCreated)
481                                         return ((TableStyle) ControlStyle).CellPadding;
482                                 return -1;
483                         }
484                         set { ((TableStyle) ControlStyle).CellPadding = value; }
485                 }
486
487                 [WebCategoryAttribute ("Layout")]
488                 [DefaultValueAttribute (0)]
489                 public virtual int CellSpacing {
490                         get {
491                                 if (ControlStyleCreated)
492                                         return ((TableStyle) ControlStyle).CellSpacing;
493                                 return 0;
494                         }
495                         set { ((TableStyle) ControlStyle).CellSpacing = value; }
496                 }
497                 
498                 [DefaultValueAttribute (null)]
499                 [WebCategoryAttribute ("Styles")]
500                 [PersistenceMode (PersistenceMode.InnerProperty)]
501                 [NotifyParentProperty (true)]
502                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
503                 public TableItemStyle CommandRowStyle {
504                         get {
505                                 if (commandRowStyle == null) {
506                                         commandRowStyle = new TableItemStyle ();
507                                         if (IsTrackingViewState)
508                                                 commandRowStyle.TrackViewState();
509                                 }
510                                 return commandRowStyle;
511                         }
512                 }
513
514                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
515                 [BrowsableAttribute (false)]
516                 public DetailsViewMode CurrentMode {
517                         get { return hasCurrentMode ? currentMode : DefaultMode; }
518
519                         private set {
520                                 hasCurrentMode = true;
521                                 currentMode = value;
522                         }
523                 }
524
525                 DetailsViewMode defaultMode = DetailsViewMode.ReadOnly;
526                 [DefaultValueAttribute (DetailsViewMode.ReadOnly)]
527                 [WebCategoryAttribute ("Behavior")]
528                 public virtual DetailsViewMode DefaultMode {
529                         get { return defaultMode; }
530                         set {
531                                 defaultMode = value;
532                                 RequireBinding ();
533                         }
534                 }
535         
536                 [EditorAttribute ("System.Web.UI.Design.WebControls.DataControlFieldTypeEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
537                 [MergablePropertyAttribute (false)]
538                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
539                 [DefaultValueAttribute (null)]
540                 [WebCategoryAttribute ("Misc")]
541                 public virtual DataControlFieldCollection Fields {
542                         get {
543                                 if (columns == null) {
544                                         columns = new DataControlFieldCollection ();
545                                         columns.FieldsChanged += new EventHandler (OnFieldsChanged);
546                                         if (IsTrackingViewState)
547                                                 ((IStateManager)columns).TrackViewState ();
548                                 }
549                                 return columns;
550                         }
551                 }
552
553                 string[] dataKeyNames = null;
554
555                 [DefaultValueAttribute (null)]
556                 [WebCategoryAttribute ("Data")]
557                 [TypeConverter (typeof(StringArrayConverter))]
558                 [EditorAttribute ("System.Web.UI.Design.WebControls.DataFieldEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
559                 public virtual string[] DataKeyNames {
560                         get {
561                                 if (dataKeyNames == null)
562                                         return emptyKeys;
563                                 else
564                                         return dataKeyNames;
565                         }
566                         set {
567                                 dataKeyNames = value;
568                                 RequireBinding ();
569                         }
570                 }
571                 
572                 IOrderedDictionary KeyTable {
573                         get {
574                                 if (_keyTable == null)
575                                         _keyTable = new OrderedDictionary (DataKeyNames.Length);
576                                 return _keyTable;
577                         }
578                 }
579
580                 [BrowsableAttribute (false)]
581                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
582                 public virtual DataKey DataKey {
583                         get {
584                                 if (key == null)
585                                         key = new DataKey (KeyTable);
586                                 return key;
587                         }
588                 }
589
590                 DataKey OldEditValues {
591                         get {
592                                 if (oldEditValues == null)
593                                         oldEditValues = new DataKey (new OrderedDictionary ());
594                                 return oldEditValues;
595                         }
596                 }
597
598                 [WebCategoryAttribute ("Styles")]
599                 [PersistenceMode (PersistenceMode.InnerProperty)]
600                 [NotifyParentProperty (true)]
601                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
602                 [DefaultValueAttribute (null)]
603                 public TableItemStyle EditRowStyle {
604                         get {
605                                 if (editRowStyle == null) {
606                                         editRowStyle = new TableItemStyle ();
607                                         if (IsTrackingViewState)
608                                                 editRowStyle.TrackViewState();
609                                 }
610                                 return editRowStyle;
611                         }
612                 }
613                 
614                 [WebCategoryAttribute ("Styles")]
615                 [PersistenceMode (PersistenceMode.InnerProperty)]
616                 [NotifyParentProperty (true)]
617                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
618                 [DefaultValueAttribute (null)]
619                 public TableItemStyle EmptyDataRowStyle {
620                         get {
621                                 if (emptyDataRowStyle == null) {
622                                         emptyDataRowStyle = new TableItemStyle ();
623                                         if (IsTrackingViewState)
624                                                 emptyDataRowStyle.TrackViewState();
625                                 }
626                                 return emptyDataRowStyle;
627                         }
628                 }
629                 
630                 [DefaultValue (null)]
631                 [TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)]
632                 [PersistenceMode (PersistenceMode.InnerProperty)]
633                 [Browsable (false)]
634                 public virtual ITemplate EmptyDataTemplate {
635                         get { return emptyDataTemplate; }
636                         set { emptyDataTemplate = value; }
637                 }
638                 
639                 [LocalizableAttribute (true)]
640                 [WebCategoryAttribute ("Appearance")]
641                 [DefaultValueAttribute ("")]
642                 public virtual string EmptyDataText {
643                         get {
644                                 object ob = ViewState ["EmptyDataText"];
645                                 if (ob != null)
646                                         return (string) ob;
647                                 return String.Empty;
648                         }
649                         set {
650                                 ViewState ["EmptyDataText"] = value;
651                                 RequireBinding ();
652                         }
653                 }
654         
655                 [WebCategoryAttribute ("Behavior")]
656                 [DefaultValueAttribute (false)]
657                 public virtual bool EnablePagingCallbacks {
658                         get {
659                                 object ob = ViewState ["EnablePagingCallbacks"];
660                                 if (ob != null)
661                                         return (bool) ob;
662                                 return false;
663                         }
664                         set {
665                                 ViewState ["EnablePagingCallbacks"] = value;
666                                 RequireBinding ();
667                         }
668                 }
669         
670                 [WebCategoryAttribute ("Styles")]
671                 [PersistenceMode (PersistenceMode.InnerProperty)]
672                 [NotifyParentProperty (true)]
673                 [DefaultValue (null)]
674                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
675                 public TableItemStyle FieldHeaderStyle {
676                         get {
677                                 if (fieldHeaderStyle == null) {
678                                         fieldHeaderStyle = new TableItemStyle ();
679                                         if (IsTrackingViewState)
680                                                 fieldHeaderStyle.TrackViewState();
681                                 }
682                                 return fieldHeaderStyle;
683                         }
684                 }
685                 
686                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
687                 [BrowsableAttribute (false)]
688                 public virtual DetailsViewRow FooterRow {
689                         get {
690                                 EnsureChildControls ();
691                                 return footerRow;
692                         }
693                 }
694         
695                 [DefaultValue (null)]
696                 [TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)]
697                 [PersistenceMode (PersistenceMode.InnerProperty)]
698                 [Browsable (false)]
699                 public virtual ITemplate FooterTemplate {
700                         get { return footerTemplate; }
701                         set { footerTemplate = value; }
702                 }
703
704                 [LocalizableAttribute (true)]
705                 [WebCategoryAttribute ("Appearance")]
706                 [DefaultValueAttribute ("")]
707                 public virtual string FooterText {
708                         get {
709                                 object ob = ViewState ["FooterText"];
710                                 if (ob != null)
711                                         return (string) ob;
712                                 return String.Empty;
713                         }
714                         set {
715                                 ViewState ["FooterText"] = value;
716                                 RequireBinding ();
717                         }
718                 }
719                 
720                 [WebCategoryAttribute ("Styles")]
721                 [PersistenceMode (PersistenceMode.InnerProperty)]
722                 [NotifyParentProperty (true)]
723                 [DefaultValue (null)]
724                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
725                 public TableItemStyle FooterStyle {
726                         get {
727                                 if (footerStyle == null) {
728                                         footerStyle = new TableItemStyle ();
729                                         if (IsTrackingViewState)
730                                                 footerStyle.TrackViewState();
731                                 }
732                                 return footerStyle;
733                         }
734                 }
735                 
736                 [WebCategoryAttribute ("Appearance")]
737                 [DefaultValueAttribute (GridLines.Both)]
738                 public virtual GridLines GridLines {
739                         get {
740                                 if (ControlStyleCreated)
741                                         return ((TableStyle) ControlStyle).GridLines;
742                                 return GridLines.Both;
743                         }
744                         set { ((TableStyle) ControlStyle).GridLines = value; }
745                 }
746
747                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
748                 [BrowsableAttribute (false)]
749                 public virtual DetailsViewRow HeaderRow {
750                         get {
751                                 EnsureChildControls ();
752                                 return headerRow;
753                         }
754                 }
755         
756                 [WebCategoryAttribute ("Styles")]
757                 [PersistenceMode (PersistenceMode.InnerProperty)]
758                 [NotifyParentProperty (true)]
759                 [DefaultValue (null)]
760                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
761                 public TableItemStyle HeaderStyle {
762                         get {
763                                 if (headerStyle == null) {
764                                         headerStyle = new TableItemStyle ();
765                                         if (IsTrackingViewState)
766                                                 headerStyle.TrackViewState();
767                                 }
768                                 return headerStyle;
769                         }
770                 }
771                 
772                 [DefaultValue (null)]
773                 [TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)]
774                 [PersistenceMode (PersistenceMode.InnerProperty)]
775                 [Browsable (false)]
776                 public virtual ITemplate HeaderTemplate {
777                         get { return headerTemplate; }
778                         set { headerTemplate = value; }
779                 }
780
781                 [LocalizableAttribute (true)]
782                 [WebCategoryAttribute ("Appearance")]
783                 [DefaultValueAttribute ("")]
784                 public virtual string HeaderText {
785                         get {
786                                 object ob = ViewState ["HeaderText"];
787                                 if (ob != null)
788                                         return (string) ob;
789                                 return String.Empty;
790                         }
791                         set {
792                                 ViewState ["HeaderText"] = value;
793                                 RequireBinding ();
794                         }
795                 }
796                 
797                 [Category ("Layout")]
798                 [DefaultValueAttribute (HorizontalAlign.NotSet)]
799                 public virtual HorizontalAlign HorizontalAlign {
800                         get {
801                                 if (ControlStyleCreated)
802                                         return ((TableStyle) ControlStyle).HorizontalAlign;
803                                 return HorizontalAlign.NotSet;
804                         }
805                         set { ((TableStyle) ControlStyle).HorizontalAlign = value; }
806                 }
807
808                 [WebCategoryAttribute ("Styles")]
809                 [PersistenceMode (PersistenceMode.InnerProperty)]
810                 [NotifyParentProperty (true)]
811                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
812                 [DefaultValueAttribute (null)]
813                 public TableItemStyle InsertRowStyle {
814                         get {
815                                 if (insertRowStyle == null) {
816                                         insertRowStyle = new TableItemStyle ();
817                                         if (IsTrackingViewState)
818                                                 insertRowStyle.TrackViewState();
819                                 }
820                                 return insertRowStyle;
821                         }
822                 }
823                 
824                 [BrowsableAttribute (false)]
825                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
826                 public virtual int PageCount {
827                         get { return pageCount; }
828                         private set { pageCount = value; }
829                 }
830
831                 [WebCategoryAttribute ("Paging")]
832                 [BindableAttribute (true, BindingDirection.OneWay)]
833                 [DefaultValueAttribute (0)]
834                 public virtual int PageIndex {
835                         get {
836                                 if (CurrentMode == DetailsViewMode.Insert)
837                                         return -1;
838                                 return pageIndex;
839                         }
840                         set {
841                                 if (value < -1)
842                                         throw new ArgumentOutOfRangeException ("PageIndex must be non-negative");
843                                 if (pageIndex == value || value == -1)
844                                         return;
845                                 pageIndex = value;
846                                 RequireBinding ();
847                         }
848                 }
849         
850                 [WebCategoryAttribute ("Paging")]
851                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
852                 [NotifyParentPropertyAttribute (true)]
853                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
854                 public virtual PagerSettings PagerSettings {
855                         get {
856                                 if (pagerSettings == null) {
857                                         pagerSettings = new PagerSettings (this);
858                                         if (IsTrackingViewState)
859                                                 ((IStateManager)pagerSettings).TrackViewState ();
860                                 }
861                                 return pagerSettings;
862                         }
863                 }
864         
865                 [WebCategoryAttribute ("Styles")]
866                 [PersistenceMode (PersistenceMode.InnerProperty)]
867                 [NotifyParentProperty (true)]
868                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
869                 public TableItemStyle PagerStyle {
870                         get {
871                                 if (pagerStyle == null) {
872                                         pagerStyle = new TableItemStyle ();
873                                         if (IsTrackingViewState)
874                                                 pagerStyle.TrackViewState();
875                                 }
876                                 return pagerStyle;
877                         }
878                 }
879                 
880                 
881                 [DefaultValue (null)]
882                 [TemplateContainer (typeof (DetailsView), BindingDirection.OneWay)]
883                 [PersistenceMode (PersistenceMode.InnerProperty)]
884                 [Browsable (false)]
885                 public virtual ITemplate PagerTemplate {
886                         get { return pagerTemplate; }
887                         set { pagerTemplate = value; }
888                 }
889                 
890                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
891                 [BrowsableAttribute (false)]
892                 public virtual DetailsViewRowCollection Rows {
893                         get {
894                                 EnsureChildControls ();
895                                 return rows;
896                         }
897                 }
898
899                 [BrowsableAttribute(false)]
900                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
901                 public IAutoFieldGenerator RowsGenerator {
902                         get;
903                         set;
904                 }
905
906                 [WebCategoryAttribute ("Styles")]
907                 [PersistenceMode (PersistenceMode.InnerProperty)]
908                 [NotifyParentProperty (true)]
909                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
910                 [DefaultValue (null)]
911                 public TableItemStyle RowStyle {
912                         get {
913                                 if (rowStyle == null) {
914                                         rowStyle = new TableItemStyle ();
915                                         if (IsTrackingViewState)
916                                                 rowStyle.TrackViewState();
917                                 }
918                                 return rowStyle;
919                         }
920                 }
921
922                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
923                 [BrowsableAttribute (false)]
924                 public object SelectedValue {
925                         get { return DataKey.Value; }
926                 }
927                 
928                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
929                 [BrowsableAttribute (false)]
930                 public virtual DetailsViewRow TopPagerRow {
931                         get {
932                                 EnsureChildControls ();
933                                 return topPagerRow;
934                         }
935                 }
936         
937                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
938                 [BrowsableAttribute (false)]
939                 public virtual object DataItem {
940                         get {
941                                 return dataItem;
942                         }
943                 }
944                 
945                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
946                 [BrowsableAttribute (false)]
947                 public int DataItemCount {
948                         get { return PageCount; }
949                 }               
950         
951                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
952                 [BrowsableAttribute (false)]
953                 public virtual int DataItemIndex {
954                         get { return PageIndex; }
955                 }               
956         
957                 int IDataItemContainer.DisplayIndex {
958                         get { return PageIndex; }
959                 }
960
961                 int IDataItemContainer.DataItemIndex {
962                         get { return DataItemIndex; }
963                 }
964
965                 [MonoTODO ("Make use of it in the code")]
966                 [DefaultValue (true)]
967                 public virtual bool EnableModelValidation {
968                         get;
969                         set;
970                 }
971
972                 public virtual bool IsBindableType (Type type)
973                 {
974                         return type.IsPrimitive || type == typeof (string) || type == typeof (DateTime) || type == typeof (Guid) || type == typeof (Decimal);
975                 }
976                 
977                 protected override DataSourceSelectArguments CreateDataSourceSelectArguments ()
978                 {
979                         DataSourceSelectArguments arg = new DataSourceSelectArguments ();
980                         DataSourceView view = GetData ();
981                         if (AllowPaging && view.CanPage) {
982                                 arg.StartRowIndex = PageIndex;
983                                 if (view.CanRetrieveTotalRowCount) {
984                                         arg.RetrieveTotalRowCount = true;
985                                         arg.MaximumRows = 1;
986                                 } else
987                                         arg.MaximumRows = -1;
988                         }
989                         return arg;
990                 }
991                 
992                 protected virtual ICollection CreateFieldSet (object dataItem, bool useDataSource)
993                 {
994                         bool autoGenerate = AutoGenerateRows;
995                         
996                         if (autoGenerate) {
997                                 IAutoFieldGenerator fieldGenerator = RowsGenerator;
998                                 if (fieldGenerator != null)
999                                         return fieldGenerator.GenerateFields (this);
1000                         }
1001                         
1002                         ArrayList fields = new ArrayList ();
1003                         
1004                         if (AutoGenerateRows) {
1005                                 if (useDataSource) {
1006                                         if (dataItem != null)
1007                                                 fields.AddRange (CreateAutoGeneratedRows (dataItem));
1008                                 } else {
1009                                         if (autoFieldProperties != null) {
1010                                                 foreach (AutoGeneratedFieldProperties props in autoFieldProperties)
1011                                                         fields.Add (CreateAutoGeneratedRow (props));
1012                                         }
1013                                 }
1014                         }
1015                         
1016                         fields.AddRange (Fields);
1017                         
1018                         if (AutoGenerateEditButton || AutoGenerateDeleteButton || AutoGenerateInsertButton) {
1019                                 CommandField field = new CommandField ();
1020                                 field.ShowEditButton = AutoGenerateEditButton;
1021                                 field.ShowDeleteButton = AutoGenerateDeleteButton;
1022                                 field.ShowInsertButton = AutoGenerateInsertButton;
1023                                 fields.Add (field);
1024                         }
1025                         
1026                         return fields;
1027                 }
1028                 
1029                 protected virtual ICollection CreateAutoGeneratedRows (object dataItem)
1030                 {
1031                         if (dataItem == null)
1032                                 return null;
1033
1034                         ArrayList list = new ArrayList ();
1035                         autoFieldProperties = CreateAutoFieldProperties (dataItem);
1036                         foreach (AutoGeneratedFieldProperties props in autoFieldProperties)
1037                                 list.Add (CreateAutoGeneratedRow (props));
1038                         return list;
1039                 }
1040                 
1041                 protected virtual AutoGeneratedField CreateAutoGeneratedRow (AutoGeneratedFieldProperties fieldProperties)
1042                 {
1043                         return new AutoGeneratedField (fieldProperties);
1044                 }
1045                 
1046                 AutoGeneratedFieldProperties[] CreateAutoFieldProperties (object dataItem)
1047                 {
1048                         if (IsBindableType (dataItem.GetType ())) {
1049                                 AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1050                                 ((IStateManager) field).TrackViewState ();
1051                                 field.Name = "Item";
1052                                 field.DataField = BoundField.ThisExpression;
1053                                 field.Type = dataItem.GetType ();
1054                                 return new AutoGeneratedFieldProperties [] { field };
1055                         }
1056
1057                         PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem, false);
1058
1059                         if (props != null && props.Count > 0) {
1060                                 ArrayList retVal = new ArrayList ();
1061                                 foreach (PropertyDescriptor current in props) {
1062                                         if (IsBindableType (current.PropertyType)) {
1063                                                 AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1064                                                 ((IStateManager) field).TrackViewState ();
1065                                                 field.Name = current.Name;
1066                                                 field.DataField = current.Name;
1067                                                 for (int i = 0; i < DataKeyNames.Length; i++) {
1068                                                         if (string.Compare (DataKeyNames [i], current.Name, StringComparison.InvariantCultureIgnoreCase) == 0) {
1069                                                                 field.IsReadOnly = true;
1070                                                                 break;
1071                                                         }
1072                                                 }
1073                                                 field.Type = current.PropertyType;
1074                                                 retVal.Add (field);
1075                                         }
1076                                 }
1077                                 if (retVal.Count > 0)
1078                                         return (AutoGeneratedFieldProperties []) retVal.ToArray (typeof (AutoGeneratedFieldProperties));
1079                         }
1080                         throw new HttpException (String.Format ("DetailsView with id '{0}' did not have any properties or attributes from which to generate fields.  Ensure that your data source has content.", ID));
1081                 }
1082                 
1083                 protected virtual DetailsViewRow CreateRow (int rowIndex, DataControlRowType rowType, DataControlRowState rowState)
1084                 {
1085                         DetailsViewRow row;
1086                         if (rowType == DataControlRowType.Pager)
1087                                 row = new DetailsViewPagerRow (rowIndex, rowType, rowState);
1088                         else
1089                                 row = new DetailsViewRow (rowIndex, rowType, rowState);
1090                         return row;
1091                 }
1092                 
1093                 void RequireBinding ()
1094                 {
1095                         if (Initialized)
1096                                 RequiresDataBinding = true;
1097                 }
1098                 
1099                 protected virtual Table CreateTable ()
1100                 {
1101                         return new ContainedTable (this);
1102                 }
1103
1104                 protected override Style CreateControlStyle ()
1105                 {
1106                         TableStyle style = new TableStyle ();
1107                         style.GridLines = GridLines.Both;
1108                         style.CellSpacing = 0;
1109                         return style;
1110                 }
1111                 
1112                 protected override int CreateChildControls (IEnumerable data, bool dataBinding)
1113                 {
1114                         PagedDataSource dataSource = new PagedDataSource ();
1115                         dataSource.DataSource = CurrentMode != DetailsViewMode.Insert ? data : null;
1116                         dataSource.AllowPaging = AllowPaging;
1117                         dataSource.PageSize = 1;
1118                         dataSource.CurrentPageIndex = PageIndex;
1119
1120                         if (dataBinding && CurrentMode != DetailsViewMode.Insert) {
1121                                 DataSourceView view = GetData ();
1122                                 if (view != null && view.CanPage) {
1123                                         dataSource.AllowServerPaging = true;
1124                                         if (SelectArguments.RetrieveTotalRowCount)
1125                                                 dataSource.VirtualCount = SelectArguments.TotalRowCount;
1126                                 }
1127                         }
1128
1129                         bool showPager = AllowPaging && (dataSource.PageCount > 1);
1130
1131                         Controls.Clear ();
1132                         table = CreateTable ();
1133                         Controls.Add (table);
1134                         headerRow = null;
1135                         footerRow = null;
1136                         topPagerRow = null;
1137                         bottomPagerRow = null;
1138                         ArrayList list = new ArrayList ();
1139
1140                         // Gets the current data item
1141
1142                         if (AllowPaging) {
1143                                 PageCount = dataSource.DataSourceCount;
1144                                 if (PageIndex >= PageCount && PageCount > 0)
1145                                         pageIndex = dataSource.CurrentPageIndex = PageCount - 1;
1146                                 if (dataSource.DataSource != null) {
1147                                         IEnumerator e = dataSource.GetEnumerator ();
1148                                         if (e.MoveNext ())
1149                                                 dataItem = e.Current;
1150                                 }
1151                         } else {
1152                                 int page = 0;
1153                                 object lastItem = null;
1154                                 if (dataSource.DataSource != null) {
1155                                         IEnumerator e = dataSource.GetEnumerator ();
1156                                         for (; e.MoveNext (); page++) {
1157                                                 lastItem = e.Current;
1158                                                 if (page == PageIndex)
1159                                                         dataItem = e.Current;
1160                                         }
1161                                 }
1162                                 PageCount = page;
1163                                 if (PageIndex >= PageCount && PageCount > 0) {
1164                                         pageIndex = PageCount - 1;
1165                                         dataItem = lastItem;
1166                                 }
1167                         }
1168
1169                         if (PageCount == 0 && CurrentMode != DetailsViewMode.Insert) {
1170                                 DetailsViewRow row = CreateEmptyRow ();
1171                                 if (row != null) {
1172                                         table.Rows.Add (row);
1173                                         list.Add (row);
1174                                 }
1175                         } else {
1176                                 // Creates the set of fields to show
1177
1178                                 ICollection fieldCollection = CreateFieldSet (dataItem, dataBinding && dataItem != null);
1179                                 DataControlField [] fields = new DataControlField [fieldCollection.Count];
1180                                 fieldCollection.CopyTo (fields, 0);
1181
1182                                 foreach (DataControlField field in fields) {
1183                                         field.Initialize (false, this);
1184                                         if (EnablePagingCallbacks)
1185                                                 field.ValidateSupportsCallback ();
1186                                 }
1187
1188                                 // Main table creation
1189
1190                                 headerRow = CreateRow (-1, DataControlRowType.Header, DataControlRowState.Normal);
1191                                 DataControlFieldCell headerCell = new DataControlFieldCell (null);
1192                                 headerCell.ColumnSpan = 2;
1193                                 if (headerTemplate != null)
1194                                         headerTemplate.InstantiateIn (headerCell);
1195                                 else if (!String.IsNullOrEmpty (HeaderText))
1196                                         headerCell.Text = HeaderText;
1197                                 else
1198                                         headerRow.Visible = false;
1199                                 headerRow.Cells.Add (headerCell);
1200                                 table.Rows.Add (headerRow);
1201
1202                                 if (showPager && PagerSettings.Position == PagerPosition.Top ||
1203                                                 PagerSettings.Position == PagerPosition.TopAndBottom) {
1204                                         topPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
1205                                         InitializePager (topPagerRow, dataSource);
1206                                         table.Rows.Add (topPagerRow);
1207                                 }
1208
1209                                 foreach (DataControlField field in fields) {
1210                                         DataControlRowState rstate = GetRowState (list.Count);
1211                                         DetailsViewRow row = CreateRow (PageIndex, DataControlRowType.DataRow, rstate);
1212                                         InitializeRow (row, field);
1213                                         table.Rows.Add (row);
1214                                         list.Add (row);
1215                                 }
1216
1217                                 footerRow = CreateRow (-1, DataControlRowType.Footer, DataControlRowState.Normal);
1218                                 DataControlFieldCell footerCell = new DataControlFieldCell (null);
1219                                 footerCell.ColumnSpan = 2;
1220                                 if (footerTemplate != null)
1221                                         footerTemplate.InstantiateIn (footerCell);
1222                                 else if (!String.IsNullOrEmpty (FooterText))
1223                                         footerCell.Text = FooterText;
1224                                 else
1225                                         footerRow.Visible = false;
1226                                 footerRow.Cells.Add (footerCell);
1227                                 table.Rows.Add (footerRow);
1228
1229                                 if (showPager && PagerSettings.Position == PagerPosition.Bottom ||
1230                                                 PagerSettings.Position == PagerPosition.TopAndBottom) {
1231                                         bottomPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
1232                                         InitializePager (bottomPagerRow, dataSource);
1233                                         table.Rows.Add (bottomPagerRow);
1234                                 }
1235                         }
1236                         
1237                         rows = new DetailsViewRowCollection (list);
1238
1239                         if (dataBinding)
1240                                 DataBind (false);
1241                         
1242                         OnItemCreated (EventArgs.Empty);
1243
1244                         return PageCount;
1245                 }
1246
1247                 protected override void EnsureDataBound ()
1248                 {
1249                         if (CurrentMode == DetailsViewMode.Insert) {
1250                                 if (RequiresDataBinding) {
1251                                         OnDataBinding (EventArgs.Empty);
1252                                         RequiresDataBinding = false;
1253                                         InternalPerformDataBinding (null);
1254                                         MarkAsDataBound ();
1255                                         OnDataBound (EventArgs.Empty);
1256                                 }
1257                         } else
1258                                 base.EnsureDataBound ();
1259                 }
1260                 
1261                 DataControlRowState GetRowState (int index)
1262                 {
1263                         DataControlRowState rstate = (index % 2) == 0 ? DataControlRowState.Normal : DataControlRowState.Alternate;
1264                         if (CurrentMode == DetailsViewMode.Edit)
1265                                 rstate |= DataControlRowState.Edit;
1266                         else if (CurrentMode == DetailsViewMode.Insert)
1267                                 rstate |= DataControlRowState.Insert;
1268                         return rstate;
1269                 }
1270                 
1271                 protected virtual void InitializePager (DetailsViewRow row, PagedDataSource dataSource)
1272                 {
1273                         TableCell cell = new TableCell ();
1274                         cell.ColumnSpan = 2;
1275                         
1276                         if (pagerTemplate != null)
1277                                 pagerTemplate.InstantiateIn (cell);
1278                         else
1279                                 cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount));
1280                         
1281                         row.Cells.Add (cell);
1282                 }
1283                 
1284                 DetailsViewRow CreateEmptyRow ()
1285                 {
1286                         TableCell cell = new TableCell ();
1287
1288                         if (emptyDataTemplate != null)
1289                                 emptyDataTemplate.InstantiateIn (cell);
1290                         else if (!String.IsNullOrEmpty (EmptyDataText))
1291                                 cell.Text = EmptyDataText;
1292                         else
1293                                 return null;
1294                         
1295                         DetailsViewRow row = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
1296                         row.Cells.Add (cell);
1297                         return row;
1298                 }
1299                 
1300                 protected virtual void InitializeRow (DetailsViewRow row, DataControlField field)
1301                 {
1302                         if (!field.Visible) {
1303                                 row.Visible = false;
1304                                 return;
1305                         }
1306                         
1307                         row.ContainingField = field;
1308                         DataControlFieldCell cell;
1309                         
1310                         if (field.ShowHeader) {
1311                                 cell = new DataControlFieldCell (field);
1312                                 row.Cells.Add (cell);
1313                                 field.InitializeCell (cell, DataControlCellType.Header, row.RowState, row.RowIndex);
1314                         }
1315                         
1316                         cell = new DataControlFieldCell (field);
1317                         if (!field.ShowHeader)
1318                                 cell.ColumnSpan = 2;
1319                         row.Cells.Add (cell);
1320                         field.InitializeCell (cell, DataControlCellType.DataCell, row.RowState, row.RowIndex);
1321
1322                         if (CurrentMode == DetailsViewMode.Insert && !field.InsertVisible)
1323                                 row.Visible = false;
1324                 }
1325                 
1326                 void FillRowDataKey (object dataItem)
1327                 {
1328                         KeyTable.Clear ();
1329
1330                         if (cachedKeyProperties == null) {
1331                                 PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem);
1332                                 cachedKeyProperties = new PropertyDescriptor [DataKeyNames.Length];
1333                                 for (int n=0; n<DataKeyNames.Length; n++) { 
1334                                         PropertyDescriptor p = props.Find (DataKeyNames [n], true);
1335                                         if (p == null)
1336                                                 throw new InvalidOperationException ("Property '" + DataKeyNames[n] + "' not found in object of type " + dataItem.GetType());
1337                                         cachedKeyProperties [n] = p;
1338                                 }
1339                         }
1340                         
1341                         foreach (PropertyDescriptor p in cachedKeyProperties)
1342                                 KeyTable [p.Name] = p.GetValue (dataItem);
1343                 }
1344                 
1345                 IOrderedDictionary GetRowValues (bool includeReadOnlyFields, bool includePrimaryKey)
1346                 {
1347                         OrderedDictionary dic = new OrderedDictionary ();
1348                         ExtractRowValues (dic, includeReadOnlyFields, includePrimaryKey);
1349                         return dic;
1350                 }
1351                 
1352                 protected virtual void ExtractRowValues (IOrderedDictionary fieldValues, bool includeReadOnlyFields, bool includePrimaryKey)
1353                 {
1354                         foreach (DetailsViewRow row in Rows) {
1355                                 if (row.Cells.Count < 1)
1356                                         continue;
1357                                 DataControlFieldCell c = row.Cells[row.Cells.Count-1] as DataControlFieldCell;
1358                                 if (c != null)
1359                                         c.ContainingField.ExtractValuesFromCell (fieldValues, c, row.RowState, includeReadOnlyFields);
1360                         }
1361                         if (!includePrimaryKey && DataKeyNames != null)
1362                                 foreach (string key in DataKeyNames)
1363                                         fieldValues.Remove (key);
1364                 }
1365                 
1366                 protected override HtmlTextWriterTag TagKey {
1367                         get {
1368                                 if (EnablePagingCallbacks)
1369                                         return HtmlTextWriterTag.Div;
1370                                 else
1371                                         return HtmlTextWriterTag.Table;
1372                         }
1373                 }
1374                 
1375                 public sealed override void DataBind ()
1376                 {
1377                         cachedKeyProperties = null;
1378                         base.DataBind ();
1379                         
1380                         if (dataItem != null) {
1381                                 if (CurrentMode == DetailsViewMode.Edit)
1382                                         oldEditValues = new DataKey (GetRowValues (false, true));
1383                                 FillRowDataKey (dataItem);
1384                                 key = new DataKey (KeyTable);
1385                         }
1386                 }
1387                 
1388                 protected internal override void PerformDataBinding (IEnumerable data)
1389                 {
1390                         base.PerformDataBinding (data);
1391                 }
1392
1393                 protected internal virtual void PrepareControlHierarchy ()
1394                 {
1395                         if (table == null)
1396                                 return;
1397
1398                         table.Caption = Caption;
1399                         table.CaptionAlign = CaptionAlign;
1400
1401                         foreach (DetailsViewRow row in table.Rows) {
1402                                 switch (row.RowType) {
1403                                         case DataControlRowType.Header:
1404                                                 if (headerStyle != null && !headerStyle.IsEmpty)
1405                                                         row.ControlStyle.CopyFrom (headerStyle);
1406                                                 break;
1407                                         case DataControlRowType.Footer:
1408                                                 if (footerStyle != null && !footerStyle.IsEmpty)
1409                                                         row.ControlStyle.CopyFrom (footerStyle);
1410                                                 break;
1411                                         case DataControlRowType.Pager:
1412                                                 if (pagerStyle != null && !pagerStyle.IsEmpty)
1413                                                         row.ControlStyle.CopyFrom (pagerStyle);
1414                                                 break;
1415                                         case DataControlRowType.EmptyDataRow:
1416                                                 if (emptyDataRowStyle != null && !emptyDataRowStyle.IsEmpty)
1417                                                         row.ControlStyle.CopyFrom (emptyDataRowStyle);
1418                                                 break;
1419                                         case DataControlRowType.DataRow:
1420                                                 if (rowStyle != null && !rowStyle.IsEmpty)
1421                                                         row.ControlStyle.CopyFrom (rowStyle);
1422                                                 if ((row.RowState & DataControlRowState.Alternate) != 0 && alternatingRowStyle != null && !alternatingRowStyle.IsEmpty)
1423                                                         row.ControlStyle.CopyFrom (alternatingRowStyle);
1424                                                 break;
1425                                         default:
1426                                                 break;
1427                                 }
1428
1429                                 if (row.ContainingField is CommandField) {
1430                                         if (commandRowStyle != null && !commandRowStyle.IsEmpty)
1431                                                 row.ControlStyle.CopyFrom (commandRowStyle);
1432                                 } else {
1433                                         if ((row.RowState & DataControlRowState.Edit) != 0 && editRowStyle != null && !editRowStyle.IsEmpty)
1434                                                 row.ControlStyle.CopyFrom (editRowStyle);
1435                                         if ((row.RowState & DataControlRowState.Insert) != 0) {
1436                                                 if (insertRowStyle != null && !insertRowStyle.IsEmpty)
1437                                                         row.ControlStyle.CopyFrom (insertRowStyle);
1438                                                 else if (editRowStyle != null && !editRowStyle.IsEmpty)
1439                                                         row.ControlStyle.CopyFrom (editRowStyle);
1440                                         }
1441                                 }
1442
1443                                 for (int n = 0; n < row.Cells.Count; n++) {
1444                                         DataControlFieldCell fcell = row.Cells [n] as DataControlFieldCell;
1445                                         if (fcell != null && fcell.ContainingField != null) {
1446                                                 DataControlField field = fcell.ContainingField;
1447                                                 if (n == 0 && field.ShowHeader) {
1448                                                         if (fieldHeaderStyle != null && !fieldHeaderStyle.IsEmpty)
1449                                                                 fcell.ControlStyle.CopyFrom (fieldHeaderStyle);
1450                                                         if (field.HeaderStyleCreated && !field.HeaderStyle.IsEmpty)
1451                                                                 fcell.ControlStyle.CopyFrom (field.HeaderStyle);
1452                                                 } else {
1453                                                         if (field.ControlStyleCreated && !field.ControlStyle.IsEmpty) {
1454                                                                 foreach (Control c in fcell.Controls) {
1455                                                                         WebControl wc = c as WebControl;
1456                                                                         if (wc != null)
1457                                                                                 wc.ControlStyle.MergeWith (field.ControlStyle);
1458                                                                 }
1459                                                         }
1460                                                         
1461                                                         if (field.ItemStyleCreated && !field.ItemStyle.IsEmpty)
1462                                                                 fcell.ControlStyle.CopyFrom (field.ItemStyle);
1463                                                 }
1464                                         }
1465                                 }
1466                         }
1467                 }
1468                 
1469                 protected internal override void OnInit (EventArgs e)
1470                 {
1471                         Page page = Page;
1472                         if (page != null)
1473                                 page.RegisterRequiresControlState (this);
1474                         base.OnInit (e);
1475                 }
1476                 
1477                 void OnFieldsChanged (object sender, EventArgs args)
1478                 {
1479                         RequireBinding ();
1480                 }
1481                 
1482                 protected override void OnDataSourceViewChanged (object sender, EventArgs e)
1483                 {
1484                         base.OnDataSourceViewChanged (sender, e);
1485                         RequireBinding ();
1486                 }
1487                 
1488                 protected override bool OnBubbleEvent (object source, EventArgs e)
1489                 {
1490                         DetailsViewCommandEventArgs args = e as DetailsViewCommandEventArgs;
1491                         if (args != null) {
1492                                 bool causesValidation = false;
1493                                 IButtonControl button = args.CommandSource as IButtonControl;
1494                                 if (button != null && button.CausesValidation) {
1495                                         Page.Validate (button.ValidationGroup);
1496                                         causesValidation = true;
1497                                 }
1498                                 ProcessCommand (args, causesValidation);
1499                                 return true;
1500                         }
1501                         return base.OnBubbleEvent (source, e);
1502                 }
1503
1504                 void ProcessCommand (DetailsViewCommandEventArgs args, bool causesValidation) {
1505                         OnItemCommand (args);
1506                         ProcessEvent (args.CommandName, args.CommandArgument as string, causesValidation);
1507                 }
1508
1509                 void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
1510                 {
1511                         RaisePostBackEvent (eventArgument);
1512                 }
1513
1514                 // TODO: This is prolly obsolete
1515                 protected virtual void RaisePostBackEvent (string eventArgument)
1516                 {
1517                         ValidateEvent (UniqueID, eventArgument);
1518                         int i = eventArgument.IndexOf ('$');
1519                         CommandEventArgs arg;
1520                         if (i != -1)
1521                                 arg = new CommandEventArgs (eventArgument.Substring (0, i), eventArgument.Substring (i + 1));
1522                         else
1523                                 arg = new CommandEventArgs (eventArgument, null);
1524                         ProcessCommand (new DetailsViewCommandEventArgs (this, arg), false);
1525                 }
1526
1527                 void ProcessEvent (string eventName, string param, bool causesValidation)
1528                 {
1529                         switch (eventName) {
1530                                 case DataControlCommands.PageCommandName:
1531                                         int newIndex = -1;
1532                                         switch (param) {
1533                                                 case DataControlCommands.FirstPageCommandArgument:
1534                                                         newIndex = 0;
1535                                                         break;
1536                                                 case DataControlCommands.LastPageCommandArgument:
1537                                                         newIndex = PageCount - 1;
1538                                                         break;
1539                                                 case DataControlCommands.NextPageCommandArgument:
1540                                                         newIndex = PageIndex + 1;
1541                                                         break;
1542                                                 case DataControlCommands.PreviousPageCommandArgument:
1543                                                         newIndex = PageIndex - 1;
1544                                                         break;
1545                                                 default:
1546                                                         int paramIndex = 0;
1547                                                         int.TryParse (param, out paramIndex);
1548                                                         newIndex = paramIndex - 1;
1549                                                         break;
1550                                         }
1551                                         SetPageIndex (newIndex);
1552                                         break;
1553                                         
1554                                 case DataControlCommands.FirstPageCommandArgument:
1555                                         SetPageIndex (0);
1556                                         break;
1557
1558                                 case DataControlCommands.LastPageCommandArgument:
1559                                         SetPageIndex (PageCount - 1);
1560                                         break;
1561                                         
1562                                 case DataControlCommands.NextPageCommandArgument:
1563                                         if (PageIndex < PageCount - 1)
1564                                                 SetPageIndex (PageIndex + 1);
1565                                         break;
1566
1567                                 case DataControlCommands.PreviousPageCommandArgument:
1568                                         if (PageIndex > 0)
1569                                                 SetPageIndex (PageIndex - 1);
1570                                         break;
1571                                         
1572                                 case DataControlCommands.EditCommandName:
1573                                         ProcessChangeMode (DetailsViewMode.Edit);
1574                                         break;
1575                                         
1576                                 case DataControlCommands.NewCommandName:
1577                                         ProcessChangeMode (DetailsViewMode.Insert);
1578                                         break;
1579                                         
1580                                 case DataControlCommands.UpdateCommandName:
1581                                         UpdateItem (param, causesValidation);
1582                                         break;
1583                                         
1584                                 case DataControlCommands.CancelCommandName:
1585                                         CancelEdit ();
1586                                         break;
1587                                         
1588                                 case DataControlCommands.DeleteCommandName:
1589                                         DeleteItem ();
1590                                         break;
1591                                         
1592                                 case DataControlCommands.InsertCommandName:
1593                                         InsertItem (causesValidation);
1594                                         break;
1595                         }
1596                 }
1597                 public
1598                 void SetPageIndex (int newIndex)
1599                 {
1600                         DetailsViewPageEventArgs args = new DetailsViewPageEventArgs (newIndex);
1601                         OnPageIndexChanging (args);
1602
1603                         if (args.Cancel || !IsBoundUsingDataSourceID)
1604                                 return;
1605                         
1606                         if (args.NewPageIndex < 0 || args.NewPageIndex >= PageCount)
1607                                 return;
1608                         EndRowEdit (false);
1609                         PageIndex = args.NewPageIndex;
1610                         OnPageIndexChanged (EventArgs.Empty);
1611                 }
1612                 
1613                 public void ChangeMode (DetailsViewMode newMode)
1614                 {
1615                         CurrentMode = newMode;
1616                         RequireBinding ();
1617                 }
1618
1619                 void ProcessChangeMode (DetailsViewMode newMode)
1620                 {
1621                         DetailsViewModeEventArgs args = new DetailsViewModeEventArgs (newMode, false);
1622                         OnModeChanging (args);
1623
1624                         if (args.Cancel || !IsBoundUsingDataSourceID)
1625                                 return;
1626
1627                         ChangeMode (args.NewMode);
1628
1629                         OnModeChanged (EventArgs.Empty);
1630                 }
1631
1632                 void CancelEdit ()
1633                 {
1634                         DetailsViewModeEventArgs args = new DetailsViewModeEventArgs (DetailsViewMode.ReadOnly, true);
1635                         OnModeChanging (args);
1636
1637                         if (args.Cancel || !IsBoundUsingDataSourceID)
1638                                 return;
1639
1640                         EndRowEdit ();
1641                 }
1642
1643                 public virtual void UpdateItem (bool causesValidation)
1644                 {
1645                         UpdateItem (null, causesValidation);
1646                 }
1647                 
1648                 void UpdateItem (string param, bool causesValidation)
1649                 {
1650                         if (causesValidation && Page != null && !Page.IsValid)
1651                                 return;
1652                         
1653                         if (CurrentMode != DetailsViewMode.Edit)
1654                                 throw new HttpException ();
1655
1656                         currentEditOldValues = OldEditValues.Values;
1657
1658                         currentEditRowKeys = DataKey.Values;
1659                         currentEditNewValues = GetRowValues (false, false);
1660                         
1661                         DetailsViewUpdateEventArgs args = new DetailsViewUpdateEventArgs (param, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1662                         OnItemUpdating (args);
1663
1664                         if (args.Cancel || !IsBoundUsingDataSourceID)
1665                                 return;
1666                         
1667                         DataSourceView view = GetData ();
1668                         if (view == null)
1669                                 throw new HttpException ("The DataSourceView associated to data bound control was null");
1670                         view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback));
1671                 }
1672
1673                 bool UpdateCallback (int recordsAffected, Exception exception)
1674                 {
1675                         DetailsViewUpdatedEventArgs dargs = new DetailsViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1676                         OnItemUpdated (dargs);
1677
1678                         if (!dargs.KeepInEditMode)                              
1679                                 EndRowEdit ();
1680
1681                         return dargs.ExceptionHandled;
1682                 }
1683
1684                 public virtual void InsertItem (bool causesValidation)
1685                 {
1686                         InsertItem (null, causesValidation);
1687                 }
1688                 
1689                 void InsertItem (string param, bool causesValidation)
1690                 {
1691                         if (causesValidation && Page != null && !Page.IsValid)
1692                                 return;
1693                         
1694                         if (CurrentMode != DetailsViewMode.Insert)
1695                                 throw new HttpException ();
1696                         
1697                         currentEditNewValues = GetRowValues (false, true);
1698                         DetailsViewInsertEventArgs args = new DetailsViewInsertEventArgs (param, currentEditNewValues);
1699                         OnItemInserting (args);
1700
1701                         if (args.Cancel || !IsBoundUsingDataSourceID)
1702                                 return;
1703
1704                         DataSourceView view = GetData ();
1705                         if (view == null)
1706                                 throw new HttpException ("The DataSourceView associated to data bound control was null");
1707                         view.Insert (currentEditNewValues, new DataSourceViewOperationCallback (InsertCallback));
1708                 }
1709                 
1710                 bool InsertCallback (int recordsAffected, Exception exception)
1711                 {
1712                         DetailsViewInsertedEventArgs dargs = new DetailsViewInsertedEventArgs (recordsAffected, exception, currentEditNewValues);
1713                         OnItemInserted (dargs);
1714
1715                         if (!dargs.KeepInInsertMode)                            
1716                                 EndRowEdit ();
1717
1718                         return dargs.ExceptionHandled;
1719                 }
1720
1721                 public virtual void DeleteItem ()
1722                 {
1723                         currentEditRowKeys = DataKey.Values;
1724                         currentEditNewValues = GetRowValues (true, false);
1725                         
1726                         DetailsViewDeleteEventArgs args = new DetailsViewDeleteEventArgs (PageIndex, currentEditRowKeys, currentEditNewValues);
1727                         OnItemDeleting (args);
1728
1729                         if (args.Cancel || !IsBoundUsingDataSourceID)
1730                                 return;
1731
1732                         DataSourceView view = GetData ();
1733                         if (view != null)
1734                                 view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
1735                         else {
1736                                 DetailsViewDeletedEventArgs dargs = new DetailsViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
1737                                 OnItemDeleted (dargs);
1738                         }
1739                         if (PageIndex > 0 && PageIndex == PageCount - 1)
1740                                 PageIndex --;
1741                         RequireBinding ();
1742                 }
1743
1744                 bool DeleteCallback (int recordsAffected, Exception exception)
1745                 {
1746                         DetailsViewDeletedEventArgs dargs = new DetailsViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues);
1747                         OnItemDeleted (dargs);
1748                         return dargs.ExceptionHandled;
1749                 }
1750                 
1751                 void EndRowEdit ()
1752                 {
1753                         EndRowEdit (true);
1754                 }
1755
1756                 void EndRowEdit (bool switchToDefaultMode)
1757                 {
1758                         if (switchToDefaultMode)
1759                                 ChangeMode (DefaultMode);
1760                         oldEditValues = new DataKey (new OrderedDictionary ());
1761                         currentEditRowKeys = null;
1762                         currentEditOldValues = null;
1763                         currentEditNewValues = null;
1764                         RequireBinding ();
1765                 }
1766
1767                 protected internal override void LoadControlState (object ob)
1768                 {
1769                         if (ob == null)
1770                                 return;
1771                         object[] state = (object[]) ob;
1772                         base.LoadControlState (state[0]);
1773                         pageIndex = (int) state[1];
1774                         pageCount = (int) state[2];
1775                         CurrentMode = (DetailsViewMode) state[3];
1776                         dataKeyNames = (string[]) state[4];
1777                         defaultMode = (DetailsViewMode) state[5];
1778                         if (state [6] != null)
1779                                 ((IStateManager) DataKey).LoadViewState (state [6]);
1780                         if (state [7] != null)
1781                                 ((IStateManager) OldEditValues).LoadViewState (state [7]);
1782                 }
1783                 
1784                 protected internal override object SaveControlState ()
1785                 {
1786                         object bstate = base.SaveControlState ();
1787                         return new object[] {
1788                                 bstate, 
1789                                 pageIndex, 
1790                                 pageCount, 
1791                                 CurrentMode, 
1792                                 dataKeyNames, 
1793                                 defaultMode,
1794                                 (key == null ? null : ((IStateManager)key).SaveViewState()),
1795                                 (oldEditValues == null ? null : ((IStateManager) oldEditValues).SaveViewState ())
1796                         };
1797                 }
1798                 
1799                 protected override void TrackViewState()
1800                 {
1801                         base.TrackViewState();
1802                         if (columns != null)
1803                                 ((IStateManager)columns).TrackViewState();
1804                         if (pagerSettings != null)
1805                                 ((IStateManager)pagerSettings).TrackViewState();
1806                         if (alternatingRowStyle != null)
1807                                 ((IStateManager)alternatingRowStyle).TrackViewState();
1808                         if (footerStyle != null)
1809                                 ((IStateManager)footerStyle).TrackViewState();
1810                         if (headerStyle != null)
1811                                 ((IStateManager)headerStyle).TrackViewState();
1812                         if (pagerStyle != null)
1813                                 ((IStateManager)pagerStyle).TrackViewState();
1814                         if (rowStyle != null)
1815                                 ((IStateManager)rowStyle).TrackViewState();
1816                         if (editRowStyle != null)
1817                                 ((IStateManager)editRowStyle).TrackViewState();
1818                         if (insertRowStyle != null)
1819                                 ((IStateManager)insertRowStyle).TrackViewState();
1820                         if (emptyDataRowStyle != null)
1821                                 ((IStateManager)emptyDataRowStyle).TrackViewState();
1822                         if (key != null)
1823                                 ((IStateManager)key).TrackViewState();
1824                         if (autoFieldProperties != null) {
1825                                 foreach (IStateManager sm in autoFieldProperties)
1826                                         sm.TrackViewState ();
1827                         }
1828                         if (ControlStyleCreated)
1829                                 ControlStyle.TrackViewState ();
1830                 }
1831
1832                 protected override object SaveViewState()
1833                 {
1834                         object[] states = new object [13];
1835                         states[0] = base.SaveViewState();
1836                         states[1] = (columns == null ? null : ((IStateManager)columns).SaveViewState());
1837                         states[2] = (pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState());
1838                         states[3] = (alternatingRowStyle == null ? null : ((IStateManager)alternatingRowStyle).SaveViewState());
1839                         states[4] = (footerStyle == null ? null : ((IStateManager)footerStyle).SaveViewState());
1840                         states[5] = (headerStyle == null ? null : ((IStateManager)headerStyle).SaveViewState());
1841                         states[6] = (pagerStyle == null ? null : ((IStateManager)pagerStyle).SaveViewState());
1842                         states[7] = (rowStyle == null ? null : ((IStateManager)rowStyle).SaveViewState());
1843                         states[8] = (insertRowStyle == null ? null : ((IStateManager)insertRowStyle).SaveViewState());
1844                         states[9] = (editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState());
1845                         states[10] = (emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).SaveViewState());
1846                         
1847                         if (autoFieldProperties != null) {
1848                                 object[] data = new object [autoFieldProperties.Length];
1849                                 bool allNull = true;
1850                                 for (int n=0; n<data.Length; n++) {
1851                                         data [n] = ((IStateManager)autoFieldProperties [n]).SaveViewState ();
1852                                         if (data [n] != null) allNull = false;
1853                                 }
1854                                 if (!allNull) states [11] = data;
1855                         }
1856                         if (ControlStyleCreated)
1857                                 states [12] = ControlStyle.SaveViewState ();
1858
1859                         for (int i = states.Length - 1; i >= 0; i--) {
1860                                 if (states [i] != null)
1861                                         return states;
1862                         }
1863
1864                         return null;
1865                 }
1866
1867                 protected override void LoadViewState (object savedState)
1868                 {
1869                         if (savedState == null) {
1870                                 base.LoadViewState (null);
1871                                 return;
1872                         }
1873
1874                         object [] states = (object []) savedState;
1875                         
1876                         if (states[11] != null) {
1877                                 object[] data = (object[]) states [11];
1878                                 autoFieldProperties = new AutoGeneratedFieldProperties [data.Length];
1879                                 for (int n=0; n<data.Length; n++) {
1880                                         IStateManager p = new AutoGeneratedFieldProperties ();
1881                                         p.TrackViewState ();
1882                                         p.LoadViewState (data [n]);
1883                                         autoFieldProperties [n] = (AutoGeneratedFieldProperties) p;
1884                                 }
1885                         }
1886
1887                         base.LoadViewState (states[0]);
1888                         
1889                         if (states[1] != null) ((IStateManager)Fields).LoadViewState (states[1]);
1890                         if (states[2] != null) ((IStateManager)PagerSettings).LoadViewState (states[2]);
1891                         if (states[3] != null) ((IStateManager)AlternatingRowStyle).LoadViewState (states[3]);
1892                         if (states[4] != null) ((IStateManager)FooterStyle).LoadViewState (states[4]);
1893                         if (states[5] != null) ((IStateManager)HeaderStyle).LoadViewState (states[5]);
1894                         if (states[6] != null) ((IStateManager)PagerStyle).LoadViewState (states[6]);
1895                         if (states[7] != null) ((IStateManager)RowStyle).LoadViewState (states[7]);
1896                         if (states[8] != null) ((IStateManager)InsertRowStyle).LoadViewState (states[8]);
1897                         if (states[9] != null) ((IStateManager)EditRowStyle).LoadViewState (states[9]);
1898                         if (states[10] != null) ((IStateManager)EmptyDataRowStyle).LoadViewState (states[10]);
1899                         if (states [12] != null)
1900                                 ControlStyle.LoadViewState (states [12]);
1901                 }
1902                 
1903                 void ICallbackEventHandler.RaiseCallbackEvent (string eventArgs)
1904                 {
1905                         RaiseCallbackEvent (eventArgs);
1906                 }
1907                 
1908                 protected virtual void RaiseCallbackEvent (string eventArgs)
1909                 {
1910                         string[] clientData = eventArgs.Split ('|');
1911                         PageIndex = int.Parse (clientData[0]);
1912                         
1913                         RaisePostBackEvent (clientData[1]);
1914                         DataBind ();
1915                 }
1916
1917                 string ICallbackEventHandler.GetCallbackResult ()
1918                 {
1919                         return GetCallbackResult ();
1920                 }
1921
1922                 protected virtual string GetCallbackResult ()
1923                 {
1924                         PrepareControlHierarchy ();
1925
1926                         StringWriter sw = new StringWriter ();
1927                         sw.Write (PageIndex.ToString () + '|');
1928
1929                         HtmlTextWriter writer = new HtmlTextWriter (sw);
1930                         RenderGrid (writer);
1931                         return sw.ToString ();
1932                 }
1933
1934                 protected virtual string GetCallbackScript (IButtonControl buttonControl, string argument)
1935                 {
1936                         if (EnablePagingCallbacks) {
1937                                 Page page = Page;
1938                                 if (page != null)
1939                                         page.ClientScript.RegisterForEventValidation (UniqueID, argument);
1940                                 return "javascript:DetailsView_ClientEvent (\"" + ClientID + "\",\"" + buttonControl.CommandName + "$" + buttonControl.CommandArgument + "\"); return false;";
1941                         } else
1942                                 return null;
1943                 }
1944                 
1945                 string ICallbackContainer.GetCallbackScript (IButtonControl control, string argument)
1946                 {
1947                         return GetCallbackScript (control, argument);
1948                 }
1949
1950                 protected override void OnPagePreLoad (object sender, EventArgs e)
1951                 {
1952                         base.OnPagePreLoad (sender, e);
1953
1954                         if (Page.IsPostBack && EnablePagingCallbacks) {
1955                                 int page;
1956                                 if (int.TryParse (Page.Request.Form [ClientID + "_Page"], out page))
1957                                         PageIndex = page;
1958                         }
1959                 }
1960
1961                 const string onPreRenderScript = @"var {0} = new Object ();
1962 {0}.pageIndex = {1};
1963 {0}.uid = {2};
1964 {0}.form = {3};
1965 ";
1966                 protected internal override void OnPreRender (EventArgs e)
1967                 {
1968                         base.OnPreRender (e);
1969
1970                         Page page = Page;
1971                         if (EnablePagingCallbacks && page != null) {
1972                                 ClientScriptManager scriptManager = page.ClientScript;
1973                                 if (!scriptManager.IsClientScriptIncludeRegistered (typeof(DetailsView), "DetailsView.js")) {
1974                                         string url = scriptManager.GetWebResourceUrl (typeof(DetailsView), "DetailsView.js");
1975                                         scriptManager.RegisterClientScriptInclude (typeof(DetailsView), "DetailsView.js", url);
1976                                 }
1977                                 scriptManager.RegisterHiddenField (ClientID + "_Page", PageIndex.ToString ());
1978                                 
1979                                 string cgrid = ClientID + "_data";
1980                                 string script = String.Format (onPreRenderScript,
1981                                                                cgrid,
1982                                                                ClientScriptManager.GetScriptLiteral (PageIndex),
1983                                                                ClientScriptManager.GetScriptLiteral (UniqueID),
1984                                                                page.theForm);
1985                                 
1986                                 scriptManager.RegisterStartupScript (typeof(TreeView), this.UniqueID, script, true);
1987                                 
1988                                 // Make sure the basic script infrastructure is rendered
1989                                 scriptManager.GetCallbackEventReference (this, "null", String.Empty, "null");
1990                                 scriptManager.GetPostBackClientHyperlink (this, String.Empty, true);
1991                         }
1992                 }
1993                 
1994                 protected internal override void Render (HtmlTextWriter writer)
1995                 {
1996                         PrepareControlHierarchy ();
1997
1998                         if (EnablePagingCallbacks)
1999                                 writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID + "_div");
2000                         writer.RenderBeginTag (HtmlTextWriterTag.Div);
2001
2002                         RenderGrid (writer);
2003
2004                         writer.RenderEndTag ();
2005                 }
2006                 
2007                 void RenderGrid (HtmlTextWriter writer)
2008                 {
2009                         if (table == null)
2010                                 return;
2011
2012                         table.Render (writer);
2013                 }
2014
2015                 PostBackOptions IPostBackContainer.GetPostBackOptions (IButtonControl control)
2016                 {
2017                         if (control == null)
2018                                 throw new ArgumentNullException ("control");
2019
2020                         if (control.CausesValidation)
2021                                 throw new InvalidOperationException ("A button that causes validation in DetailsView '" + 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.");
2022
2023                         PostBackOptions options = new PostBackOptions (this);
2024                         options.Argument = control.CommandName + "$" + control.CommandArgument;
2025                         options.RequiresJavaScriptProtocol = true;
2026
2027                         return options;
2028                 }
2029         }
2030 }