2009-06-12 Bill Holmes <billholmes54@gmail.com>
[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                 [BrowsableAttribute(false)]
881                 public IAutoFieldGenerator RowsGenerator {
882                         get;
883                         set;
884                 }
885
886                 [WebCategoryAttribute ("Styles")]
887                 [PersistenceMode (PersistenceMode.InnerProperty)]
888                 [NotifyParentProperty (true)]
889                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
890                 [DefaultValue (null)]
891                 public TableItemStyle RowStyle {
892                         get {
893                                 if (rowStyle == null) {
894                                         rowStyle = new TableItemStyle ();
895                                         if (IsTrackingViewState)
896                                                 rowStyle.TrackViewState();
897                                 }
898                                 return rowStyle;
899                         }
900                 }
901
902                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
903                 [BrowsableAttribute (false)]
904                 public object SelectedValue {
905                         get { return DataKey.Value; }
906                 }
907                 
908                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
909                 [BrowsableAttribute (false)]
910                 public virtual DetailsViewRow TopPagerRow {
911                         get {
912                                 EnsureChildControls ();
913                                 return topPagerRow;
914                         }
915                 }
916         
917                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
918                 [BrowsableAttribute (false)]
919                 public virtual object DataItem {
920                         get {
921                                 return dataItem;
922                         }
923                 }
924                 
925                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
926                 [BrowsableAttribute (false)]
927                 public int DataItemCount {
928                         get { return PageCount; }
929                 }               
930         
931                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
932                 [BrowsableAttribute (false)]
933                 public virtual int DataItemIndex {
934                         get { return PageIndex; }
935                 }               
936         
937                 int IDataItemContainer.DisplayIndex {
938                         get { return PageIndex; }
939                 }
940
941                 int IDataItemContainer.DataItemIndex {
942                         get { return DataItemIndex; }
943                 }
944         
945                 public virtual bool IsBindableType (Type type)
946                 {
947                         return type.IsPrimitive || type == typeof (string) || type == typeof (DateTime) || type == typeof (Guid) || type == typeof (Decimal);
948                 }
949                 
950                 protected override DataSourceSelectArguments CreateDataSourceSelectArguments ()
951                 {
952                         DataSourceSelectArguments arg = new DataSourceSelectArguments ();
953                         DataSourceView view = GetData ();
954                         if (AllowPaging && view.CanPage) {
955                                 arg.StartRowIndex = PageIndex;
956                                 if (view.CanRetrieveTotalRowCount) {
957                                         arg.RetrieveTotalRowCount = true;
958                                         arg.MaximumRows = 1;
959                                 }
960                                 else {
961                                         arg.MaximumRows = -1;
962                                 }
963                         }
964                         return arg;
965                 }
966                 
967                 protected virtual ICollection CreateFieldSet (object dataItem, bool useDataSource)
968                 {
969                         bool autoGenerate = AutoGenerateRows;
970                         
971                         if (autoGenerate) {
972                                 IAutoFieldGenerator fieldGenerator = RowsGenerator;
973                                 if (fieldGenerator != null)
974                                         return fieldGenerator.GenerateFields (this);
975                         }
976                         
977                         ArrayList fields = new ArrayList ();
978                         
979                         if (AutoGenerateRows) {
980                                 if (useDataSource) {
981                                         if (dataItem != null)
982                                                 fields.AddRange (CreateAutoGeneratedRows (dataItem));
983                                 } else {
984                                         if (autoFieldProperties != null) {
985                                                 foreach (AutoGeneratedFieldProperties props in autoFieldProperties)
986                                                         fields.Add (CreateAutoGeneratedRow (props));
987                                         }
988                                 }
989                         }
990                         
991                         fields.AddRange (Fields);
992                         
993                         if (AutoGenerateEditButton || AutoGenerateDeleteButton || AutoGenerateInsertButton) {
994                                 CommandField field = new CommandField ();
995                                 field.ShowEditButton = AutoGenerateEditButton;
996                                 field.ShowDeleteButton = AutoGenerateDeleteButton;
997                                 field.ShowInsertButton = AutoGenerateInsertButton;
998                                 fields.Add (field);
999                         }
1000                         
1001                         return fields;
1002                 }
1003                 
1004                 protected virtual ICollection CreateAutoGeneratedRows (object dataItem)
1005                 {
1006                         if (dataItem == null)
1007                                 return null;
1008
1009                         ArrayList list = new ArrayList ();
1010                         autoFieldProperties = CreateAutoFieldProperties (dataItem);
1011                         foreach (AutoGeneratedFieldProperties props in autoFieldProperties)
1012                                 list.Add (CreateAutoGeneratedRow (props));
1013                         return list;
1014                 }
1015                 
1016                 protected virtual AutoGeneratedField CreateAutoGeneratedRow (AutoGeneratedFieldProperties fieldProperties)
1017                 {
1018                         return new AutoGeneratedField (fieldProperties);
1019                 }
1020                 
1021                 AutoGeneratedFieldProperties[] CreateAutoFieldProperties (object dataItem)
1022                 {
1023                         if (IsBindableType (dataItem.GetType ()))
1024                         {
1025                                 AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1026                                 ((IStateManager) field).TrackViewState ();
1027                                 field.Name = "Item";
1028                                 field.DataField = BoundField.ThisExpression;
1029                                 field.Type = dataItem.GetType ();
1030                                 return new AutoGeneratedFieldProperties [] { field };
1031                         }
1032
1033                         PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem, false);
1034
1035                         if (props != null && props.Count > 0) {
1036                                 ArrayList retVal = new ArrayList ();
1037                                 foreach (PropertyDescriptor current in props) {
1038                                         if (IsBindableType (current.PropertyType)) {
1039                                                 AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1040                                                 ((IStateManager) field).TrackViewState ();
1041                                                 field.Name = current.Name;
1042                                                 field.DataField = current.Name;
1043                                                 for (int i = 0; i < DataKeyNames.Length; i++) {
1044                                                         if (string.Compare (DataKeyNames [i], current.Name, StringComparison.InvariantCultureIgnoreCase) == 0) {
1045                                                                 field.IsReadOnly = true;
1046                                                                 break;
1047                                                         }
1048                                                 }
1049                                                 field.Type = current.PropertyType;
1050                                                 retVal.Add (field);
1051                                         }
1052                                 }
1053                                 if (retVal.Count > 0)
1054                                         return (AutoGeneratedFieldProperties []) retVal.ToArray (typeof (AutoGeneratedFieldProperties));
1055                         }
1056                         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));
1057                 }
1058                 
1059                 protected virtual DetailsViewRow CreateRow (int rowIndex, DataControlRowType rowType, DataControlRowState rowState)
1060                 {
1061                         DetailsViewRow row;
1062                         if (rowType == DataControlRowType.Pager)
1063                                 row = new DetailsViewPagerRow (rowIndex, rowType, rowState);
1064                         else
1065                                 row = new DetailsViewRow (rowIndex, rowType, rowState);
1066                         return row;
1067                 }
1068                 
1069                 void RequireBinding ()
1070                 {
1071                         if (Initialized) {
1072                                 RequiresDataBinding = true;
1073                         }
1074                 }
1075                 
1076                 protected virtual Table CreateTable ()
1077                 {
1078                         return new ContainedTable (this);
1079                 }
1080
1081                 protected override Style CreateControlStyle ()
1082                 {
1083                         TableStyle style = new TableStyle ();
1084                         style.GridLines = GridLines.Both;
1085                         style.CellSpacing = 0;
1086                         return style;
1087                 }
1088                 
1089                 protected override int CreateChildControls (IEnumerable data, bool dataBinding)
1090                 {
1091                         PagedDataSource dataSource = new PagedDataSource ();
1092                         dataSource.DataSource = CurrentMode != DetailsViewMode.Insert ? data : null;
1093                         dataSource.AllowPaging = AllowPaging;
1094                         dataSource.PageSize = 1;
1095                         dataSource.CurrentPageIndex = PageIndex;
1096
1097                         if (dataBinding && CurrentMode != DetailsViewMode.Insert) {
1098                                 DataSourceView view = GetData ();
1099                                 if (view != null && view.CanPage) {
1100                                         dataSource.AllowServerPaging = true;
1101                                         if (SelectArguments.RetrieveTotalRowCount)
1102                                                 dataSource.VirtualCount = SelectArguments.TotalRowCount;
1103                                 }
1104                         }
1105
1106                         bool showPager = AllowPaging && (dataSource.PageCount > 1);
1107
1108                         Controls.Clear ();
1109                         table = CreateTable ();
1110                         Controls.Add (table);
1111                         headerRow = null;
1112                         footerRow = null;
1113                         topPagerRow = null;
1114                         bottomPagerRow = null;
1115                         ArrayList list = new ArrayList ();
1116
1117                         // Gets the current data item
1118
1119                         if (AllowPaging) {
1120                                 PageCount = dataSource.DataSourceCount;
1121                                 if (PageIndex >= PageCount && PageCount > 0) {
1122                                         pageIndex = dataSource.CurrentPageIndex = PageCount - 1;
1123                                 }
1124                                 if (dataSource.DataSource != null) {
1125                                         IEnumerator e = dataSource.GetEnumerator ();
1126                                         if (e.MoveNext ())
1127                                                 dataItem = e.Current;
1128                                 }
1129                         }
1130                         else {
1131                                 int page = 0;
1132                                 object lastItem = null;
1133                                 if (dataSource.DataSource != null) {
1134                                         IEnumerator e = dataSource.GetEnumerator ();
1135                                         for (; e.MoveNext (); page++) {
1136                                                 lastItem = e.Current;
1137                                                 if (page == PageIndex)
1138                                                         dataItem = e.Current;
1139                                         }
1140                                 }
1141                                 PageCount = page;
1142                                 if (PageIndex >= PageCount && PageCount > 0) {
1143                                         pageIndex = PageCount - 1;
1144                                         dataItem = lastItem;
1145                                 }
1146                         }
1147
1148                         if (PageCount == 0 && CurrentMode != DetailsViewMode.Insert) {
1149                                 DetailsViewRow row = CreateEmptyRow ();
1150                                 if (row != null) {
1151                                         table.Rows.Add (row);
1152                                         list.Add (row);
1153                                 }
1154                         }
1155                         else {
1156
1157                                 // Creates the set of fields to show
1158
1159                                 ICollection fieldCollection = CreateFieldSet (dataItem, dataBinding && dataItem != null);
1160                                 DataControlField [] fields = new DataControlField [fieldCollection.Count];
1161                                 fieldCollection.CopyTo (fields, 0);
1162
1163                                 foreach (DataControlField field in fields) {
1164                                         field.Initialize (false, this);
1165                                         if (EnablePagingCallbacks)
1166                                                 field.ValidateSupportsCallback ();
1167                                 }
1168
1169                                 // Main table creation
1170
1171                                 headerRow = CreateRow (-1, DataControlRowType.Header, DataControlRowState.Normal);
1172                                 DataControlFieldCell headerCell = new DataControlFieldCell (null);
1173                                 headerCell.ColumnSpan = 2;
1174                                 if (headerTemplate != null)
1175                                         headerTemplate.InstantiateIn (headerCell);
1176                                 else if (!String.IsNullOrEmpty (HeaderText))
1177                                         headerCell.Text = HeaderText;
1178                                 else
1179                                         headerRow.Visible = false;
1180                                 headerRow.Cells.Add (headerCell);
1181                                 table.Rows.Add (headerRow);
1182
1183                                 if (showPager && PagerSettings.Position == PagerPosition.Top ||
1184                                                 PagerSettings.Position == PagerPosition.TopAndBottom) {
1185                                         topPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
1186                                         InitializePager (topPagerRow, dataSource);
1187                                         table.Rows.Add (topPagerRow);
1188                                 }
1189
1190                                 foreach (DataControlField field in fields) {
1191                                         DataControlRowState rstate = GetRowState (list.Count);
1192                                         DetailsViewRow row = CreateRow (PageIndex, DataControlRowType.DataRow, rstate);
1193                                         InitializeRow (row, field);
1194                                         table.Rows.Add (row);
1195                                         list.Add (row);
1196                                 }
1197
1198                                 footerRow = CreateRow (-1, DataControlRowType.Footer, DataControlRowState.Normal);
1199                                 DataControlFieldCell footerCell = new DataControlFieldCell (null);
1200                                 footerCell.ColumnSpan = 2;
1201                                 if (footerTemplate != null)
1202                                         footerTemplate.InstantiateIn (footerCell);
1203                                 else if (!String.IsNullOrEmpty (FooterText))
1204                                         footerCell.Text = FooterText;
1205                                 else
1206                                         footerRow.Visible = false;
1207                                 footerRow.Cells.Add (footerCell);
1208                                 table.Rows.Add (footerRow);
1209
1210                                 if (showPager && PagerSettings.Position == PagerPosition.Bottom ||
1211                                                 PagerSettings.Position == PagerPosition.TopAndBottom) {
1212                                         bottomPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
1213                                         InitializePager (bottomPagerRow, dataSource);
1214                                         table.Rows.Add (bottomPagerRow);
1215                                 }
1216                         }
1217                         
1218                         rows = new DetailsViewRowCollection (list);
1219
1220                         if (dataBinding)
1221                                 DataBind (false);
1222                         
1223                         OnItemCreated (EventArgs.Empty);
1224
1225                         return PageCount;
1226                 }
1227
1228                 protected override void EnsureDataBound ()
1229                 {
1230                         if (CurrentMode == DetailsViewMode.Insert) {
1231                                 if (RequiresDataBinding) {
1232                                         OnDataBinding (EventArgs.Empty);
1233                                         RequiresDataBinding = false;
1234                                         InternalPerformDataBinding (null);
1235                                         MarkAsDataBound ();
1236                                         OnDataBound (EventArgs.Empty);
1237                                 }
1238                         }
1239                         else
1240                                 base.EnsureDataBound ();
1241                 }
1242                 
1243                 DataControlRowState GetRowState (int index)
1244                 {
1245                         DataControlRowState rstate = (index % 2) == 0 ? DataControlRowState.Normal : DataControlRowState.Alternate;
1246                         if (CurrentMode == DetailsViewMode.Edit) rstate |= DataControlRowState.Edit;
1247                         else if (CurrentMode == DetailsViewMode.Insert) rstate |= DataControlRowState.Insert;
1248                         return rstate;
1249                 }
1250                 
1251                 protected virtual void InitializePager (DetailsViewRow row, PagedDataSource dataSource)
1252                 {
1253                         TableCell cell = new TableCell ();
1254                         cell.ColumnSpan = 2;
1255                         
1256                         if (pagerTemplate != null)
1257                                 pagerTemplate.InstantiateIn (cell);
1258                         else
1259                                 cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount));
1260                         
1261                         row.Cells.Add (cell);
1262                 }
1263                 
1264                 DetailsViewRow CreateEmptyRow ()
1265                 {
1266                         TableCell cell = new TableCell ();
1267
1268                         if (emptyDataTemplate != null)
1269                                 emptyDataTemplate.InstantiateIn (cell);
1270                         else if (!String.IsNullOrEmpty (EmptyDataText))
1271                                 cell.Text = EmptyDataText;
1272                         else
1273                                 return null;
1274                         
1275                         DetailsViewRow row = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
1276                         row.Cells.Add (cell);
1277                         return row;
1278                 }
1279                 
1280                 protected virtual void InitializeRow (DetailsViewRow row, DataControlField field)
1281                 {
1282                         if (!field.Visible) {
1283                                 row.Visible = false;
1284                                 return;
1285                         }
1286                         
1287                         row.ContainingField = field;
1288                         DataControlFieldCell cell;
1289                         
1290                         if (field.ShowHeader) {
1291                                 cell = new DataControlFieldCell (field);
1292                                 row.Cells.Add (cell);
1293                                 field.InitializeCell (cell, DataControlCellType.Header, row.RowState, row.RowIndex);
1294                         }
1295                         
1296                         cell = new DataControlFieldCell (field);
1297                         if (!field.ShowHeader)
1298                                 cell.ColumnSpan = 2;
1299                         row.Cells.Add (cell);
1300                         field.InitializeCell (cell, DataControlCellType.DataCell, row.RowState, row.RowIndex);
1301
1302                         if (CurrentMode == DetailsViewMode.Insert && !field.InsertVisible)
1303                                 row.Visible = false;
1304                 }
1305                 
1306                 void FillRowDataKey (object dataItem)
1307                 {
1308                         KeyTable.Clear ();
1309
1310                         if (cachedKeyProperties == null) {
1311                                 PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem);
1312                                 cachedKeyProperties = new PropertyDescriptor [DataKeyNames.Length];
1313                                 for (int n=0; n<DataKeyNames.Length; n++) { 
1314                                         PropertyDescriptor p = props.Find (DataKeyNames [n], true);
1315                                         if (p == null)
1316                                                 throw new InvalidOperationException ("Property '" + DataKeyNames[n] + "' not found in object of type " + dataItem.GetType());
1317                                         cachedKeyProperties [n] = p;
1318                                 }
1319                         }
1320                         
1321                         foreach (PropertyDescriptor p in cachedKeyProperties)
1322                                 KeyTable [p.Name] = p.GetValue (dataItem);
1323                 }
1324                 
1325                 IOrderedDictionary GetRowValues (bool includeReadOnlyFields, bool includePrimaryKey)
1326                 {
1327                         OrderedDictionary dic = new OrderedDictionary ();
1328                         ExtractRowValues (dic, includeReadOnlyFields, includePrimaryKey);
1329                         return dic;
1330                 }
1331                 
1332                 protected virtual void ExtractRowValues (IOrderedDictionary fieldValues, bool includeReadOnlyFields, bool includePrimaryKey)
1333                 {
1334                         foreach (DetailsViewRow row in Rows) {
1335                                 if (row.Cells.Count < 1) continue;
1336                                 DataControlFieldCell c = row.Cells[row.Cells.Count-1] as DataControlFieldCell;
1337                                 if (c != null)
1338                                         c.ContainingField.ExtractValuesFromCell (fieldValues, c, row.RowState, includeReadOnlyFields);
1339                         }
1340                         if (!includePrimaryKey && DataKeyNames != null)
1341                                 foreach (string key in DataKeyNames)
1342                                         fieldValues.Remove (key);
1343                 }
1344                 
1345                 protected override HtmlTextWriterTag TagKey {
1346                         get {
1347                                 if (EnablePagingCallbacks)
1348                                         return HtmlTextWriterTag.Div;
1349                                 else
1350                                         return HtmlTextWriterTag.Table;
1351                         }
1352                 }
1353                 
1354                 public sealed override void DataBind ()
1355                 {
1356                         cachedKeyProperties = null;
1357                         base.DataBind ();
1358                         
1359                         if (dataItem != null) {
1360                                 if (CurrentMode == DetailsViewMode.Edit)
1361                                         oldEditValues = new DataKey (GetRowValues (false, true));
1362                                 FillRowDataKey (dataItem);
1363                                 key = new DataKey (KeyTable);
1364                         }
1365                 }
1366                 
1367                 protected internal override void PerformDataBinding (IEnumerable data)
1368                 {
1369                         base.PerformDataBinding (data);
1370                 }
1371
1372                 protected internal virtual void PrepareControlHierarchy ()
1373                 {
1374                         if (table == null)
1375                                 return;
1376
1377                         table.Caption = Caption;
1378                         table.CaptionAlign = CaptionAlign;
1379
1380                         foreach (DetailsViewRow row in table.Rows) {
1381                                 switch (row.RowType) {
1382                                 case DataControlRowType.Header:
1383                                         if (headerStyle != null && !headerStyle.IsEmpty)
1384                                                 row.ControlStyle.CopyFrom (headerStyle);
1385                                         break;
1386                                 case DataControlRowType.Footer:
1387                                         if (footerStyle != null && !footerStyle.IsEmpty)
1388                                                 row.ControlStyle.CopyFrom (footerStyle);
1389                                         break;
1390                                 case DataControlRowType.Pager:
1391                                         if (pagerStyle != null && !pagerStyle.IsEmpty)
1392                                                 row.ControlStyle.CopyFrom (pagerStyle);
1393                                         break;
1394                                 case DataControlRowType.EmptyDataRow:
1395                                         if (emptyDataRowStyle != null && !emptyDataRowStyle.IsEmpty)
1396                                                 row.ControlStyle.CopyFrom (emptyDataRowStyle);
1397                                         break;
1398                                 case DataControlRowType.DataRow:
1399                                         if (rowStyle != null && !rowStyle.IsEmpty)
1400                                                 row.ControlStyle.CopyFrom (rowStyle);
1401                                         if ((row.RowState & DataControlRowState.Alternate) != 0 && alternatingRowStyle != null && !alternatingRowStyle.IsEmpty)
1402                                                 row.ControlStyle.CopyFrom (alternatingRowStyle);
1403                                         break;
1404                                 default:
1405                                         break;
1406                                 }
1407
1408                                 if (row.ContainingField is CommandField) {
1409                                         if (commandRowStyle != null && !commandRowStyle.IsEmpty)
1410                                                 row.ControlStyle.CopyFrom (commandRowStyle);
1411                                 }
1412                                 else {
1413                                         if ((row.RowState & DataControlRowState.Edit) != 0 && editRowStyle != null && !editRowStyle.IsEmpty)
1414                                                 row.ControlStyle.CopyFrom (editRowStyle);
1415                                         if ((row.RowState & DataControlRowState.Insert) != 0) {
1416                                                 if (insertRowStyle != null && !insertRowStyle.IsEmpty)
1417                                                         row.ControlStyle.CopyFrom (insertRowStyle);
1418                                                 else if (editRowStyle != null && !editRowStyle.IsEmpty)
1419                                                         row.ControlStyle.CopyFrom (editRowStyle);
1420                                         }
1421                                 }
1422
1423                                 for (int n = 0; n < row.Cells.Count; n++) {
1424                                         DataControlFieldCell fcell = row.Cells [n] as DataControlFieldCell;
1425                                         if (fcell != null && fcell.ContainingField != null) {
1426                                                 DataControlField field = fcell.ContainingField;
1427                                                 if (n == 0 && field.ShowHeader) {
1428                                                         if (fieldHeaderStyle != null && !fieldHeaderStyle.IsEmpty)
1429                                                                 fcell.ControlStyle.CopyFrom (fieldHeaderStyle);
1430                                                         if (field.HeaderStyleCreated && !field.HeaderStyle.IsEmpty)
1431                                                                 fcell.ControlStyle.CopyFrom (field.HeaderStyle);
1432                                                 }
1433                                                 else {
1434                                                         if (field.ControlStyleCreated && !field.ControlStyle.IsEmpty)
1435                                                                 foreach (Control c in fcell.Controls) {
1436                                                                         WebControl wc = c as WebControl;
1437                                                                         if (wc != null)
1438                                                                                 wc.ControlStyle.MergeWith (field.ControlStyle);
1439                                                                 }
1440                                                         if (field.ItemStyleCreated && !field.ItemStyle.IsEmpty)
1441                                                                 fcell.ControlStyle.CopyFrom (field.ItemStyle);
1442                                                 }
1443                                         }
1444                                 }
1445                         }
1446                 }
1447                 
1448                 protected internal override void OnInit (EventArgs e)
1449                 {
1450                         Page.RegisterRequiresControlState (this);
1451                         base.OnInit (e);
1452                 }
1453                 
1454                 void OnFieldsChanged (object sender, EventArgs args)
1455                 {
1456                         RequireBinding ();
1457                 }
1458                 
1459                 protected override void OnDataSourceViewChanged (object sender, EventArgs e)
1460                 {
1461                         base.OnDataSourceViewChanged (sender, e);
1462                         RequireBinding ();
1463                 }
1464                 
1465                 protected override bool OnBubbleEvent (object source, EventArgs e)
1466                 {
1467                         DetailsViewCommandEventArgs args = e as DetailsViewCommandEventArgs;
1468                         if (args != null) {
1469                                 bool causesValidation = false;
1470                                 IButtonControl button = args.CommandSource as IButtonControl;
1471                                 if (button != null && button.CausesValidation) {
1472                                         Page.Validate (button.ValidationGroup);
1473                                         causesValidation = true;
1474                                 }
1475                                 ProcessCommand (args, causesValidation);
1476                                 return true;
1477                         }
1478                         return base.OnBubbleEvent (source, e);
1479                 }
1480
1481                 void ProcessCommand (DetailsViewCommandEventArgs args, bool causesValidation) {
1482                         OnItemCommand (args);
1483                         ProcessEvent (args.CommandName, args.CommandArgument as string, causesValidation);
1484                 }
1485
1486                 void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
1487                 {
1488                         RaisePostBackEvent (eventArgument);
1489                 }
1490
1491                 // TODO: This is prolly obsolete
1492                 protected virtual void RaisePostBackEvent (string eventArgument)
1493                 {
1494                         ValidateEvent (UniqueID, eventArgument);
1495                         int i = eventArgument.IndexOf ('$');
1496                         CommandEventArgs arg;
1497                         if (i != -1)
1498                                 arg = new CommandEventArgs (eventArgument.Substring (0, i), eventArgument.Substring (i + 1));
1499                         else
1500                                 arg = new CommandEventArgs (eventArgument, null);
1501                         ProcessCommand (new DetailsViewCommandEventArgs (this, arg), false);
1502                 }
1503
1504                 void ProcessEvent (string eventName, string param, bool causesValidation)
1505                 {
1506                         switch (eventName)
1507                         {
1508                         case DataControlCommands.PageCommandName:
1509                                 int newIndex = -1;
1510                                 switch (param) {
1511                                 case DataControlCommands.FirstPageCommandArgument:
1512                                         newIndex = 0;
1513                                         break;
1514                                 case DataControlCommands.LastPageCommandArgument:
1515                                         newIndex = PageCount - 1;
1516                                         break;
1517                                 case DataControlCommands.NextPageCommandArgument:
1518                                         newIndex = PageIndex + 1;
1519                                         break;
1520                                 case DataControlCommands.PreviousPageCommandArgument:
1521                                         newIndex = PageIndex - 1;
1522                                         break;
1523                                 default:
1524                                         int paramIndex = 0;
1525                                         int.TryParse (param, out paramIndex);
1526                                         newIndex = paramIndex - 1;
1527                                         break;
1528                                 }
1529                                 ShowPage (newIndex);
1530                                 break;
1531                                         
1532                         case DataControlCommands.FirstPageCommandArgument:
1533                                 ShowPage (0);
1534                                 break;
1535
1536                         case DataControlCommands.LastPageCommandArgument:
1537                                 ShowPage (PageCount - 1);
1538                                 break;
1539                                         
1540                         case DataControlCommands.NextPageCommandArgument:
1541                                 if (PageIndex < PageCount - 1)
1542                                         ShowPage (PageIndex + 1);
1543                                 break;
1544
1545                         case DataControlCommands.PreviousPageCommandArgument:
1546                                 if (PageIndex > 0)
1547                                         ShowPage (PageIndex - 1);
1548                                 break;
1549                                         
1550                         case DataControlCommands.EditCommandName:
1551                                 ProcessChangeMode (DetailsViewMode.Edit);
1552                                 break;
1553                                         
1554                         case DataControlCommands.NewCommandName:
1555                                 ProcessChangeMode (DetailsViewMode.Insert);
1556                                 break;
1557                                         
1558                         case DataControlCommands.UpdateCommandName:
1559                                 UpdateItem (param, causesValidation);
1560                                 break;
1561                                         
1562                         case DataControlCommands.CancelCommandName:
1563                                 CancelEdit ();
1564                                 break;
1565                                         
1566                         case DataControlCommands.DeleteCommandName:
1567                                 DeleteItem ();
1568                                 break;
1569                                         
1570                         case DataControlCommands.InsertCommandName:
1571                                 InsertItem (causesValidation);
1572                                 break;
1573                         }
1574                 }
1575                 
1576                 void ShowPage (int newIndex)
1577                 {
1578                         DetailsViewPageEventArgs args = new DetailsViewPageEventArgs (newIndex);
1579                         OnPageIndexChanging (args);
1580
1581                         if (args.Cancel || !IsBoundUsingDataSourceID)
1582                                 return;
1583                         
1584                         if (args.NewPageIndex < 0 || args.NewPageIndex >= PageCount)
1585                                 return;
1586                         EndRowEdit (false);
1587                         PageIndex = args.NewPageIndex;
1588                         OnPageIndexChanged (EventArgs.Empty);
1589                 }
1590                 
1591                 public void ChangeMode (DetailsViewMode newMode)
1592                 {
1593                         CurrentMode = newMode;
1594                         RequireBinding ();
1595                 }
1596
1597                 void ProcessChangeMode (DetailsViewMode newMode)
1598                 {
1599                         DetailsViewModeEventArgs args = new DetailsViewModeEventArgs (newMode, false);
1600                         OnModeChanging (args);
1601
1602                         if (args.Cancel || !IsBoundUsingDataSourceID)
1603                                 return;
1604
1605                         ChangeMode (args.NewMode);
1606
1607                         OnModeChanged (EventArgs.Empty);
1608                 }
1609
1610                 void CancelEdit ()
1611                 {
1612                         DetailsViewModeEventArgs args = new DetailsViewModeEventArgs (DetailsViewMode.ReadOnly, true);
1613                         OnModeChanging (args);
1614
1615                         if (args.Cancel || !IsBoundUsingDataSourceID)
1616                                 return;
1617
1618                         EndRowEdit ();
1619                 }
1620
1621                 public virtual void UpdateItem (bool causesValidation)
1622                 {
1623                         UpdateItem (null, causesValidation);
1624                 }
1625                 
1626                 void UpdateItem (string param, bool causesValidation)
1627                 {
1628                         if (causesValidation && Page != null && !Page.IsValid)
1629                                 return;
1630                         
1631                         if (CurrentMode != DetailsViewMode.Edit) throw new HttpException ();
1632
1633                         currentEditOldValues = OldEditValues.Values;
1634
1635                         currentEditRowKeys = DataKey.Values;
1636                         currentEditNewValues = GetRowValues (false, false);
1637                         
1638                         DetailsViewUpdateEventArgs args = new DetailsViewUpdateEventArgs (param, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1639                         OnItemUpdating (args);
1640
1641                         if (args.Cancel || !IsBoundUsingDataSourceID)
1642                                 return;
1643                         
1644                         DataSourceView view = GetData ();
1645                         if (view == null)
1646                                 throw new HttpException ("The DataSourceView associated to data bound control was null");
1647                         view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback));
1648                 }
1649
1650                 bool UpdateCallback (int recordsAffected, Exception exception)
1651                 {
1652                         DetailsViewUpdatedEventArgs dargs = new DetailsViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1653                         OnItemUpdated (dargs);
1654
1655                         if (!dargs.KeepInEditMode)                              
1656                                 EndRowEdit ();
1657
1658                         return dargs.ExceptionHandled;
1659                 }
1660
1661                 public virtual void InsertItem (bool causesValidation)
1662                 {
1663                         InsertItem (null, causesValidation);
1664                 }
1665                 
1666                 void InsertItem (string param, bool causesValidation)
1667                 {
1668                         if (causesValidation && Page != null && !Page.IsValid)
1669                                 return;
1670                         
1671                         if (CurrentMode != DetailsViewMode.Insert) throw new HttpException ();
1672                         
1673                         currentEditNewValues = GetRowValues (false, true);
1674                         DetailsViewInsertEventArgs args = new DetailsViewInsertEventArgs (param, currentEditNewValues);
1675                         OnItemInserting (args);
1676
1677                         if (args.Cancel || !IsBoundUsingDataSourceID)
1678                                 return;
1679
1680                         DataSourceView view = GetData ();
1681                         if (view == null)
1682                                 throw new HttpException ("The DataSourceView associated to data bound control was null");
1683                         view.Insert (currentEditNewValues, new DataSourceViewOperationCallback (InsertCallback));
1684                 }
1685                 
1686                 bool InsertCallback (int recordsAffected, Exception exception)
1687                 {
1688                         DetailsViewInsertedEventArgs dargs = new DetailsViewInsertedEventArgs (recordsAffected, exception, currentEditNewValues);
1689                         OnItemInserted (dargs);
1690
1691                         if (!dargs.KeepInInsertMode)                            
1692                                 EndRowEdit ();
1693
1694                         return dargs.ExceptionHandled;
1695                 }
1696
1697                 public virtual void DeleteItem ()
1698                 {
1699                         currentEditRowKeys = DataKey.Values;
1700                         currentEditNewValues = GetRowValues (true, false);
1701                         
1702                         DetailsViewDeleteEventArgs args = new DetailsViewDeleteEventArgs (PageIndex, currentEditRowKeys, currentEditNewValues);
1703                         OnItemDeleting (args);
1704
1705                         if (args.Cancel || !IsBoundUsingDataSourceID)
1706                                 return;
1707
1708                         DataSourceView view = GetData ();
1709                         if (view != null)
1710                                 view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
1711                         else {
1712                                 DetailsViewDeletedEventArgs dargs = new DetailsViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
1713                                 OnItemDeleted (dargs);
1714                         }
1715                         if (PageIndex > 0 && PageIndex == PageCount - 1)
1716                                 PageIndex --;
1717                         RequireBinding ();
1718                 }
1719
1720                 bool DeleteCallback (int recordsAffected, Exception exception)
1721                 {
1722                         DetailsViewDeletedEventArgs dargs = new DetailsViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues);
1723                         OnItemDeleted (dargs);
1724                         return dargs.ExceptionHandled;
1725                 }
1726                 
1727                 void EndRowEdit ()
1728                 {
1729                         EndRowEdit (true);
1730                 }
1731
1732                 void EndRowEdit (bool switchToDefaultMode) {
1733                         if (switchToDefaultMode)
1734                                 ChangeMode (DefaultMode);
1735                         oldEditValues = new DataKey (new OrderedDictionary ());
1736                         currentEditRowKeys = null;
1737                         currentEditOldValues = null;
1738                         currentEditNewValues = null;
1739                         RequireBinding ();
1740                 }
1741
1742                 protected internal override void LoadControlState (object ob)
1743                 {
1744                         if (ob == null) return;
1745                         object[] state = (object[]) ob;
1746                         base.LoadControlState (state[0]);
1747                         pageIndex = (int) state[1];
1748                         pageCount = (int) state[2];
1749                         CurrentMode = (DetailsViewMode) state[3];
1750                         dataKeyNames = (string[]) state[4];
1751                         defaultMode = (DetailsViewMode) state[5];
1752                         if (state [6] != null)
1753                                 ((IStateManager) DataKey).LoadViewState (state [6]);
1754                         if (state [7] != null)
1755                                 ((IStateManager) OldEditValues).LoadViewState (state [7]);
1756                 }
1757                 
1758                 protected internal override object SaveControlState ()
1759                 {
1760                         object bstate = base.SaveControlState ();
1761                         return new object[] {
1762                                 bstate, 
1763                                 pageIndex, 
1764                                 pageCount, 
1765                                 CurrentMode, 
1766                                 dataKeyNames, 
1767                                 defaultMode,
1768                                 (key == null ? null : ((IStateManager)key).SaveViewState()),
1769                                 (oldEditValues == null ? null : ((IStateManager) oldEditValues).SaveViewState ())
1770                                         };
1771                 }
1772                 
1773                 protected override void TrackViewState()
1774                 {
1775                         base.TrackViewState();
1776                         if (columns != null) ((IStateManager)columns).TrackViewState();
1777                         if (pagerSettings != null) ((IStateManager)pagerSettings).TrackViewState();
1778                         if (alternatingRowStyle != null) ((IStateManager)alternatingRowStyle).TrackViewState();
1779                         if (footerStyle != null) ((IStateManager)footerStyle).TrackViewState();
1780                         if (headerStyle != null) ((IStateManager)headerStyle).TrackViewState();
1781                         if (pagerStyle != null) ((IStateManager)pagerStyle).TrackViewState();
1782                         if (rowStyle != null) ((IStateManager)rowStyle).TrackViewState();
1783                         if (editRowStyle != null) ((IStateManager)editRowStyle).TrackViewState();
1784                         if (insertRowStyle != null) ((IStateManager)insertRowStyle).TrackViewState();
1785                         if (emptyDataRowStyle != null) ((IStateManager)emptyDataRowStyle).TrackViewState();
1786                         if (key != null) ((IStateManager)key).TrackViewState();
1787                         if (autoFieldProperties != null) {
1788                                 foreach (IStateManager sm in autoFieldProperties)
1789                                         sm.TrackViewState ();
1790                         }
1791                         if (ControlStyleCreated)
1792                                 ControlStyle.TrackViewState ();
1793                 }
1794
1795                 protected override object SaveViewState()
1796                 {
1797                         object[] states = new object [13];
1798                         states[0] = base.SaveViewState();
1799                         states[1] = (columns == null ? null : ((IStateManager)columns).SaveViewState());
1800                         states[2] = (pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState());
1801                         states[3] = (alternatingRowStyle == null ? null : ((IStateManager)alternatingRowStyle).SaveViewState());
1802                         states[4] = (footerStyle == null ? null : ((IStateManager)footerStyle).SaveViewState());
1803                         states[5] = (headerStyle == null ? null : ((IStateManager)headerStyle).SaveViewState());
1804                         states[6] = (pagerStyle == null ? null : ((IStateManager)pagerStyle).SaveViewState());
1805                         states[7] = (rowStyle == null ? null : ((IStateManager)rowStyle).SaveViewState());
1806                         states[8] = (insertRowStyle == null ? null : ((IStateManager)insertRowStyle).SaveViewState());
1807                         states[9] = (editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState());
1808                         states[10] = (emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).SaveViewState());
1809                         
1810                         if (autoFieldProperties != null) {
1811                                 object[] data = new object [autoFieldProperties.Length];
1812                                 bool allNull = true;
1813                                 for (int n=0; n<data.Length; n++) {
1814                                         data [n] = ((IStateManager)autoFieldProperties [n]).SaveViewState ();
1815                                         if (data [n] != null) allNull = false;
1816                                 }
1817                                 if (!allNull) states [11] = data;
1818                         }
1819                         if (ControlStyleCreated)
1820                                 states [12] = ControlStyle.SaveViewState ();
1821
1822                         for (int i = states.Length - 1; i >= 0; i--) {
1823                                 if (states [i] != null)
1824                                         return states;
1825                         }
1826
1827                         return null;
1828                 }
1829
1830                 protected override void LoadViewState (object savedState)
1831                 {
1832                         if (savedState == null) {
1833                                 base.LoadViewState (null);
1834                                 return;
1835                         }
1836
1837                         object [] states = (object []) savedState;
1838                         
1839                         if (states[11] != null) {
1840                                 object[] data = (object[]) states [11];
1841                                 autoFieldProperties = new AutoGeneratedFieldProperties [data.Length];
1842                                 for (int n=0; n<data.Length; n++) {
1843                                         IStateManager p = new AutoGeneratedFieldProperties ();
1844                                         p.TrackViewState ();
1845                                         p.LoadViewState (data [n]);
1846                                         autoFieldProperties [n] = (AutoGeneratedFieldProperties) p;
1847                                 }
1848                         }
1849
1850                         base.LoadViewState (states[0]);
1851                         
1852                         if (states[1] != null) ((IStateManager)Fields).LoadViewState (states[1]);
1853                         if (states[2] != null) ((IStateManager)PagerSettings).LoadViewState (states[2]);
1854                         if (states[3] != null) ((IStateManager)AlternatingRowStyle).LoadViewState (states[3]);
1855                         if (states[4] != null) ((IStateManager)FooterStyle).LoadViewState (states[4]);
1856                         if (states[5] != null) ((IStateManager)HeaderStyle).LoadViewState (states[5]);
1857                         if (states[6] != null) ((IStateManager)PagerStyle).LoadViewState (states[6]);
1858                         if (states[7] != null) ((IStateManager)RowStyle).LoadViewState (states[7]);
1859                         if (states[8] != null) ((IStateManager)InsertRowStyle).LoadViewState (states[8]);
1860                         if (states[9] != null) ((IStateManager)EditRowStyle).LoadViewState (states[9]);
1861                         if (states[10] != null) ((IStateManager)EmptyDataRowStyle).LoadViewState (states[10]);
1862                         if (states [12] != null)
1863                                 ControlStyle.LoadViewState (states [12]);
1864                 }
1865                 
1866                 void ICallbackEventHandler.RaiseCallbackEvent (string eventArgs)
1867                 {
1868                         RaiseCallbackEvent (eventArgs);
1869                 }
1870                 
1871                 protected virtual void RaiseCallbackEvent (string eventArgs)
1872                 {
1873                         string[] clientData = eventArgs.Split ('|');
1874                         PageIndex = int.Parse (clientData[0]);
1875                         
1876                         RaisePostBackEvent (clientData[1]);
1877                         DataBind ();
1878                 }
1879
1880                 string ICallbackEventHandler.GetCallbackResult ()
1881                 {
1882                         return GetCallbackResult ();
1883                 }
1884
1885                 protected virtual string GetCallbackResult ()
1886                 {
1887                         PrepareControlHierarchy ();
1888
1889                         StringWriter sw = new StringWriter ();
1890                         sw.Write (PageIndex.ToString () + '|');
1891
1892                         HtmlTextWriter writer = new HtmlTextWriter (sw);
1893                         RenderGrid (writer);
1894                         return sw.ToString ();
1895                 }
1896
1897                 protected virtual string GetCallbackScript (IButtonControl buttonControl, string argument)
1898                 {
1899                         if (EnablePagingCallbacks) {
1900                                 Page page = Page;
1901                                 if (page != null)
1902                                         page.ClientScript.RegisterForEventValidation (UniqueID, argument);
1903                                 return "javascript:DetailsView_ClientEvent (\"" + ClientID + "\",\"" + buttonControl.CommandName + "$" + buttonControl.CommandArgument + "\"); return false;";
1904                         } else
1905                                 return null;
1906                 }
1907                 
1908                 string ICallbackContainer.GetCallbackScript (IButtonControl control, string argument)
1909                 {
1910                         return GetCallbackScript (control, argument);
1911                 }
1912
1913                 protected override void OnPagePreLoad (object sender, EventArgs e)
1914                 {
1915                         base.OnPagePreLoad (sender, e);
1916
1917                         if (Page.IsPostBack && EnablePagingCallbacks) {
1918                                 int page;
1919                                 if (int.TryParse (Page.Request.Form [ClientID + "_Page"], out page))
1920                                         PageIndex = page;
1921                         }
1922                 }
1923
1924                 const string onPreRenderScript = @"var {0} = new Object ();
1925 {0}.pageIndex = {1};
1926 {0}.uid = {2};
1927 {0}.form = {3};
1928 ";
1929
1930                 protected internal override void OnPreRender (EventArgs e)
1931                 {
1932                         base.OnPreRender (e);
1933
1934                         if (EnablePagingCallbacks)
1935                         {
1936                                 if (!Page.ClientScript.IsClientScriptIncludeRegistered (typeof(DetailsView), "DetailsView.js")) {
1937                                         string url = Page.ClientScript.GetWebResourceUrl (typeof(DetailsView), "DetailsView.js");
1938                                         Page.ClientScript.RegisterClientScriptInclude (typeof(DetailsView), "DetailsView.js", url);
1939                                 }
1940                                 Page.ClientScript.RegisterHiddenField (ClientID + "_Page", PageIndex.ToString ());
1941                                 
1942                                 string cgrid = ClientID + "_data";
1943                                 string script = String.Format (onPreRenderScript,
1944                                                                cgrid,
1945                                                                ClientScriptManager.GetScriptLiteral (PageIndex),
1946                                                                ClientScriptManager.GetScriptLiteral (UniqueID),
1947                                                                Page.theForm);
1948                                 
1949                                 Page.ClientScript.RegisterStartupScript (typeof(TreeView), this.UniqueID, script, true);
1950                                 
1951                                 // Make sure the basic script infrastructure is rendered
1952                                 Page.ClientScript.GetCallbackEventReference (this, "null", "", "null");
1953                                 Page.ClientScript.GetPostBackClientHyperlink (this, String.Empty, true);
1954                         }
1955                 }
1956                 
1957                 protected internal override void Render (HtmlTextWriter writer)
1958                 {
1959                         PrepareControlHierarchy ();
1960
1961                         if (EnablePagingCallbacks)
1962                                 writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID + "_div");
1963                         writer.RenderBeginTag (HtmlTextWriterTag.Div);
1964
1965                         RenderGrid (writer);
1966
1967                         writer.RenderEndTag ();
1968                 }
1969                 
1970                 void RenderGrid (HtmlTextWriter writer)
1971                 {
1972                         if (table == null)
1973                                 return;
1974
1975                         table.Render (writer);
1976                 }
1977
1978                 PostBackOptions IPostBackContainer.GetPostBackOptions (IButtonControl control)
1979                 {
1980                         if (control == null)
1981                                 throw new ArgumentNullException ("control");
1982
1983                         if (control.CausesValidation)
1984                                 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.");
1985
1986                         PostBackOptions options = new PostBackOptions (this);
1987                         options.Argument = control.CommandName + "$" + control.CommandArgument;
1988                         options.RequiresJavaScriptProtocol = true;
1989
1990                         return options;
1991                 }
1992         }
1993 }
1994
1995 #endif