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