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