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