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