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