2006-10-08 Igor Zelmanovich <igorz@mainsoft.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / FormView.cs
1 //
2 // System.Web.UI.WebControls.FormView.cs
3 //
4 // Authors:
5 //      Lluis Sanchez Gual (lluis@novell.com)
6 //
7 // (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 #if NET_2_0
30
31 using System;
32 using System.Collections;
33 using System.Collections.Specialized;
34 using System.ComponentModel;
35 using System.Web.UI;
36 using System.Security.Permissions;
37 using System.Text;
38 using System.IO;
39 using System.Reflection;
40
41 namespace System.Web.UI.WebControls
42 {
43         [SupportsEventValidation]
44         [DesignerAttribute ("System.Web.UI.Design.WebControls.FormViewDesigner, " + Consts.AssemblySystem_Design, "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 FormView: CompositeDataBoundControl, IDataItemContainer, INamingContainer, IPostBackEventHandler, IPostBackContainer
50         {
51                 object dataItem;
52                 
53                 Table table;
54                 FormViewRow headerRow;
55                 FormViewRow footerRow;
56                 FormViewRow bottomPagerRow;
57                 FormViewRow topPagerRow;
58                 FormViewRow itemRow;
59                 
60                 IOrderedDictionary currentEditRowKeys;
61                 IOrderedDictionary currentEditNewValues;
62                 IOrderedDictionary currentEditOldValues;
63                 
64                 ITemplate pagerTemplate;
65                 ITemplate emptyDataTemplate;
66                 ITemplate headerTemplate;
67                 ITemplate footerTemplate;
68                 ITemplate editItemTemplate;
69                 ITemplate insertItemTemplate;
70                 ITemplate itemTemplate;
71                 
72                 PropertyDescriptor[] cachedKeyProperties;
73                 readonly string[] emptyKeys = new string[0];
74                 
75                 // View state
76                 PagerSettings pagerSettings;
77                 
78                 TableItemStyle editRowStyle;
79                 TableItemStyle insertRowStyle;
80                 TableItemStyle emptyDataRowStyle;
81                 TableItemStyle footerStyle;
82                 TableItemStyle headerStyle;
83                 TableItemStyle pagerStyle;
84                 TableItemStyle rowStyle;
85                 
86                 DataKey key;
87                 DataKey oldEditValues;
88                 
89                 private static readonly object PageIndexChangedEvent = new object();
90                 private static readonly object PageIndexChangingEvent = new object();
91                 private static readonly object ItemCommandEvent = new object();
92                 private static readonly object ItemCreatedEvent = new object();
93                 private static readonly object ItemDeletedEvent = new object();
94                 private static readonly object ItemDeletingEvent = new object();
95                 private static readonly object ItemInsertedEvent = new object();
96                 private static readonly object ItemInsertingEvent = new object();
97                 private static readonly object ModeChangingEvent = new object();
98                 private static readonly object ModeChangedEvent = new object();
99                 private static readonly object ItemUpdatedEvent = new object();
100                 private static readonly object ItemUpdatingEvent = new object();
101                 
102                 // Control state
103                 int pageIndex;
104                 FormViewMode currentMode = FormViewMode.ReadOnly; 
105                 bool hasCurrentMode;
106                 int pageCount = 0;
107                 
108                 public FormView ()
109                 {
110                         key = new DataKey (new OrderedDictionary ());
111                 }
112                 
113                 public event EventHandler PageIndexChanged {
114                         add { Events.AddHandler (PageIndexChangedEvent, value); }
115                         remove { Events.RemoveHandler (PageIndexChangedEvent, value); }
116                 }
117                 
118                 public event FormViewPageEventHandler PageIndexChanging {
119                         add { Events.AddHandler (PageIndexChangingEvent, value); }
120                         remove { Events.RemoveHandler (PageIndexChangingEvent, value); }
121                 }
122                 
123                 public event FormViewCommandEventHandler ItemCommand {
124                         add { Events.AddHandler (ItemCommandEvent, value); }
125                         remove { Events.RemoveHandler (ItemCommandEvent, value); }
126                 }
127                 
128                 public event EventHandler ItemCreated {
129                         add { Events.AddHandler (ItemCreatedEvent, value); }
130                         remove { Events.RemoveHandler (ItemCreatedEvent, value); }
131                 }
132                 
133                 public event FormViewDeletedEventHandler ItemDeleted {
134                         add { Events.AddHandler (ItemDeletedEvent, value); }
135                         remove { Events.RemoveHandler (ItemDeletedEvent, value); }
136                 }
137                 
138                 public event FormViewDeleteEventHandler ItemDeleting {
139                         add { Events.AddHandler (ItemDeletingEvent, value); }
140                         remove { Events.RemoveHandler (ItemDeletingEvent, value); }
141                 }
142                 
143                 public event FormViewInsertedEventHandler ItemInserted {
144                         add { Events.AddHandler (ItemInsertedEvent, value); }
145                         remove { Events.RemoveHandler (ItemInsertedEvent, value); }
146                 }
147                 
148                 public event FormViewInsertEventHandler ItemInserting {
149                         add { Events.AddHandler (ItemInsertingEvent, value); }
150                         remove { Events.RemoveHandler (ItemInsertingEvent, value); }
151                 }
152                 
153                 public event FormViewModeEventHandler ModeChanging {
154                         add { Events.AddHandler (ModeChangingEvent, value); }
155                         remove { Events.RemoveHandler (ModeChangingEvent, value); }
156                 }
157                 
158                 public event EventHandler ModeChanged {
159                         add { Events.AddHandler (ModeChangedEvent, value); }
160                         remove { Events.RemoveHandler (ModeChangedEvent, value); }
161                 }
162                 
163                 public event FormViewUpdatedEventHandler ItemUpdated {
164                         add { Events.AddHandler (ItemUpdatedEvent, value); }
165                         remove { Events.RemoveHandler (ItemUpdatedEvent, value); }
166                 }
167                 
168                 public event FormViewUpdateEventHandler ItemUpdating {
169                         add { Events.AddHandler (ItemUpdatingEvent, value); }
170                         remove { Events.RemoveHandler (ItemUpdatingEvent, value); }
171                 }
172                 
173                 protected virtual void OnPageIndexChanged (EventArgs e)
174                 {
175                         if (Events != null) {
176                                 EventHandler eh = (EventHandler) Events [PageIndexChangedEvent];
177                                 if (eh != null) eh (this, e);
178                         }
179                 }
180                 
181                 protected virtual void OnPageIndexChanging (FormViewPageEventArgs e)
182                 {
183                         if (Events != null) {
184                                 FormViewPageEventHandler eh = (FormViewPageEventHandler) Events [PageIndexChangingEvent];
185                                 if (eh != null) eh (this, e);
186                         }
187                 }
188                 
189                 protected virtual void OnItemCommand (FormViewCommandEventArgs e)
190                 {
191                         if (Events != null) {
192                                 FormViewCommandEventHandler eh = (FormViewCommandEventHandler) Events [ItemCommandEvent];
193                                 if (eh != null) eh (this, e);
194                         }
195                 }
196                 
197                 protected virtual void OnItemCreated (EventArgs e)
198                 {
199                         if (Events != null) {
200                                 EventHandler eh = (EventHandler) Events [ItemCreatedEvent];
201                                 if (eh != null) eh (this, e);
202                         }
203                 }
204                 
205                 protected virtual void OnItemDeleted (FormViewDeletedEventArgs e)
206                 {
207                         if (Events != null) {
208                                 FormViewDeletedEventHandler eh = (FormViewDeletedEventHandler) Events [ItemDeletedEvent];
209                                 if (eh != null) eh (this, e);
210                         }
211                 }
212                 
213                 protected virtual void OnItemInserted (FormViewInsertedEventArgs e)
214                 {
215                         if (Events != null) {
216                                 FormViewInsertedEventHandler eh = (FormViewInsertedEventHandler) Events [ItemInsertedEvent];
217                                 if (eh != null) eh (this, e);
218                         }
219                 }
220                 
221                 protected virtual void OnItemInserting (FormViewInsertEventArgs e)
222                 {
223                         if (Events != null) {
224                                 FormViewInsertEventHandler eh = (FormViewInsertEventHandler) Events [ItemInsertingEvent];
225                                 if (eh != null) eh (this, e);
226                         }
227                 }
228                 
229                 protected virtual void OnItemDeleting (FormViewDeleteEventArgs e)
230                 {
231                         if (Events != null) {
232                                 FormViewDeleteEventHandler eh = (FormViewDeleteEventHandler) Events [ItemDeletingEvent];
233                                 if (eh != null) eh (this, e);
234                         }
235                 }
236                 
237                 protected virtual void OnModeChanged (EventArgs e)
238                 {
239                         if (Events != null) {
240                                 EventHandler eh = (EventHandler) Events [ModeChangedEvent];
241                                 if (eh != null) eh (this, e);
242                         }
243                 }
244                 
245                 protected virtual void OnModeChanging (FormViewModeEventArgs e)
246                 {
247                         if (Events != null) {
248                                 FormViewModeEventHandler eh = (FormViewModeEventHandler) Events [ModeChangingEvent];
249                                 if (eh != null) eh (this, e);
250                         }
251                 }
252                 
253                 protected virtual void OnItemUpdated (FormViewUpdatedEventArgs e)
254                 {
255                         if (Events != null) {
256                                 FormViewUpdatedEventHandler eh = (FormViewUpdatedEventHandler) Events [ItemUpdatedEvent];
257                                 if (eh != null) eh (this, e);
258                         }
259                 }
260                 
261                 protected virtual void OnItemUpdating (FormViewUpdateEventArgs e)
262                 {
263                         if (Events != null) {
264                                 FormViewUpdateEventHandler eh = (FormViewUpdateEventHandler) Events [ItemUpdatingEvent];
265                                 if (eh != null) eh (this, e);
266                         }
267                 }
268                 
269                 
270                 [WebCategoryAttribute ("Paging")]
271                 [DefaultValueAttribute (false)]
272                 public virtual bool AllowPaging {
273                         get {
274                                 object ob = ViewState ["AllowPaging"];
275                                 if (ob != null) return (bool) ob;
276                                 return false;
277                         }
278                         set {
279                                 ViewState ["AllowPaging"] = value;
280                                 RequireBinding ();
281                         }
282                 }
283                 
284                 [UrlPropertyAttribute]
285                 [WebCategoryAttribute ("Appearance")]
286                 [DefaultValueAttribute ("")]
287                 [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
288                 public virtual string BackImageUrl {
289                         get {
290                                 if (ControlStyleCreated)
291                                         return ((TableStyle) ControlStyle).BackImageUrl;
292                                 return String.Empty;
293                         }
294                         set {
295                                 ((TableStyle) ControlStyle).BackImageUrl = value;
296                         }
297                 }
298
299                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
300                 [BrowsableAttribute (false)]
301                 public virtual FormViewRow BottomPagerRow {
302                         get {
303                                 EnsureDataBound ();
304                                 return bottomPagerRow;
305                         }
306                 }
307         
308                 [WebCategoryAttribute ("Accessibility")]
309                 [DefaultValueAttribute ("")]
310                 [LocalizableAttribute (true)]
311                 public virtual string Caption {
312                         get {
313                                 object ob = ViewState ["Caption"];
314                                 if (ob != null) return (string) ob;
315                                 return string.Empty;
316                         }
317                         set {
318                                 ViewState ["Caption"] = value;
319                                 RequireBinding ();
320                         }
321                 }
322                 
323                 [WebCategoryAttribute ("Accessibility")]
324                 [DefaultValueAttribute (TableCaptionAlign.NotSet)]
325                 public virtual TableCaptionAlign CaptionAlign
326                 {
327                         get {
328                                 object o = ViewState ["CaptionAlign"];
329                                 if(o != null) return (TableCaptionAlign) o;
330                                 return TableCaptionAlign.NotSet;
331                         }
332                         set {
333                                 ViewState ["CaptionAlign"] = value;
334                                 RequireBinding ();
335                         }
336                 }
337
338                 [WebCategoryAttribute ("Layout")]
339                 [DefaultValueAttribute (-1)]
340                 public virtual int CellPadding
341                 {
342                         get {
343                                 if (ControlStyleCreated)
344                                         return ((TableStyle) ControlStyle).CellPadding;
345                                 return -1;
346                         }
347                         set {
348                                 ((TableStyle) ControlStyle).CellPadding = value;
349                         }
350                 }
351
352                 [WebCategoryAttribute ("Layout")]
353                 [DefaultValueAttribute (0)]
354                 public virtual int CellSpacing
355                 {
356                         get {
357                                 if (ControlStyleCreated)
358                                         return ((TableStyle) ControlStyle).CellSpacing;
359                                 return 0;
360                         }
361                         set {
362                                 ((TableStyle) ControlStyle).CellSpacing = value;
363                         }
364                 }
365                 
366                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
367                 [BrowsableAttribute (false)]
368                 public FormViewMode CurrentMode {
369                         get {
370                                 return hasCurrentMode ? currentMode : DefaultMode;
371                         }
372                         private set {
373                                 hasCurrentMode = true;
374                                 currentMode = value;
375                         }
376                 }
377
378                 FormViewMode defaultMode;
379
380                 [DefaultValueAttribute (FormViewMode.ReadOnly)]
381                 [WebCategoryAttribute ("Behavior")]
382                 public virtual FormViewMode DefaultMode {
383                         get {
384                                 return defaultMode;
385                         }
386                         set {
387                                 defaultMode = value;
388                                 RequireBinding ();
389                         }
390                 }
391
392                 string[] dataKeyNames;
393                 [DefaultValueAttribute (null)]
394                 [WebCategoryAttribute ("Data")]
395                 [TypeConverter (typeof(StringArrayConverter))]
396                 [EditorAttribute ("System.Web.UI.Design.WebControls.DataFieldEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
397                 public virtual string[] DataKeyNames
398                 {
399                         get {
400                                 if (dataKeyNames == null)
401                                         return emptyKeys;
402                                 return dataKeyNames;
403                         }
404                         set {
405                                 dataKeyNames = value;
406                                 RequireBinding ();
407                         }
408                 }
409                 
410                 [BrowsableAttribute (false)]
411                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
412                 public virtual DataKey DataKey {
413                         get {
414                                 EnsureDataBound ();
415                                 return key;
416                         }
417                 }
418
419                 [DefaultValue (null)]
420                 [TemplateContainer (typeof(FormView), BindingDirection.TwoWay)]
421                 [PersistenceMode (PersistenceMode.InnerProperty)]
422                 [Browsable (false)]
423                 public virtual ITemplate EditItemTemplate {
424                         get { return editItemTemplate; }
425                         set { editItemTemplate = value; RequireBinding (); }
426                 }
427
428                 [WebCategoryAttribute ("Styles")]
429                 [PersistenceMode (PersistenceMode.InnerProperty)]
430                 [NotifyParentProperty (true)]
431                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
432                 [DefaultValueAttribute (null)]
433                 public TableItemStyle EditRowStyle {
434                         get {
435                                 if (editRowStyle == null) {
436                                         editRowStyle = new TableItemStyle ();
437                                         if (IsTrackingViewState)
438                                                 editRowStyle.TrackViewState();
439                                 }
440                                 return editRowStyle;
441                         }
442                 }
443                 
444                 [WebCategoryAttribute ("Styles")]
445                 [PersistenceMode (PersistenceMode.InnerProperty)]
446                 [NotifyParentProperty (true)]
447                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
448                 [DefaultValueAttribute (null)]
449                 public TableItemStyle EmptyDataRowStyle {
450                         get {
451                                 if (emptyDataRowStyle == null) {
452                                         emptyDataRowStyle = new TableItemStyle ();
453                                         if (IsTrackingViewState)
454                                                 emptyDataRowStyle.TrackViewState();
455                                 }
456                                 return emptyDataRowStyle;
457                         }
458                 }
459                 
460                 [DefaultValue (null)]
461                 [TemplateContainer (typeof(FormView), BindingDirection.OneWay)]
462                 [PersistenceMode (PersistenceMode.InnerProperty)]
463                 [Browsable (false)]
464                 public virtual ITemplate EmptyDataTemplate {
465                         get { return emptyDataTemplate; }
466                         set { emptyDataTemplate = value; RequireBinding (); }
467                 }
468                 
469                 [LocalizableAttribute (true)]
470                 [WebCategoryAttribute ("Appearance")]
471                 [DefaultValueAttribute ("")]
472                 public virtual string EmptyDataText {
473                         get {
474                                 object ob = ViewState ["EmptyDataText"];
475                                 if (ob != null) return (string) ob;
476                                 return string.Empty;
477                         }
478                         set {
479                                 ViewState ["EmptyDataText"] = value;
480                                 RequireBinding ();
481                         }
482                 }
483         
484                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
485                 [BrowsableAttribute (false)]
486                 public virtual FormViewRow FooterRow {
487                         get {
488                                 EnsureChildControls ();
489                                 return footerRow;
490                         }
491                 }
492         
493                 [DefaultValue (null)]
494                 [TemplateContainer (typeof(FormView), BindingDirection.OneWay)]
495                 [PersistenceMode (PersistenceMode.InnerProperty)]
496                 [Browsable (false)]
497                 public virtual ITemplate FooterTemplate {
498                         get { return footerTemplate; }
499                         set { footerTemplate = value; RequireBinding (); }
500                 }
501
502                 [LocalizableAttribute (true)]
503                 [WebCategoryAttribute ("Appearance")]
504                 [DefaultValueAttribute ("")]
505                 public virtual string FooterText {
506                         get {
507                                 object ob = ViewState ["FooterText"];
508                                 if (ob != null) return (string) ob;
509                                 return string.Empty;
510                         }
511                         set {
512                                 ViewState ["FooterText"] = value;
513                                 RequireBinding ();
514                         }
515                 }
516                 
517                 [WebCategoryAttribute ("Styles")]
518                 [PersistenceMode (PersistenceMode.InnerProperty)]
519                 [NotifyParentProperty (true)]
520                 [DefaultValue (null)]
521                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
522                 public TableItemStyle FooterStyle {
523                         get {
524                                 if (footerStyle == null) {
525                                         footerStyle = new TableItemStyle ();
526                                         if (IsTrackingViewState)
527                                                 footerStyle.TrackViewState();
528                                 }
529                                 return footerStyle;
530                         }
531                 }
532                 
533                 [WebCategoryAttribute ("Appearance")]
534                 [DefaultValueAttribute (GridLines.None)]
535                 public virtual GridLines GridLines {
536                         get {
537                                 if (ControlStyleCreated)
538                                         return ((TableStyle) ControlStyle).GridLines;
539                                 return GridLines.None;
540                         }
541                         set {
542                                 ((TableStyle) ControlStyle).GridLines = value;
543                         }
544                 }
545
546                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
547                 [BrowsableAttribute (false)]
548                 public virtual FormViewRow HeaderRow {
549                         get {
550                                 EnsureChildControls ();
551                                 return headerRow;
552                         }
553                 }
554         
555                 [WebCategoryAttribute ("Styles")]
556                 [PersistenceMode (PersistenceMode.InnerProperty)]
557                 [NotifyParentProperty (true)]
558                 [DefaultValue (null)]
559                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
560                 public TableItemStyle HeaderStyle {
561                         get {
562                                 if (headerStyle == null) {
563                                         headerStyle = new TableItemStyle ();
564                                         if (IsTrackingViewState)
565                                                 headerStyle.TrackViewState();
566                                 }
567                                 return headerStyle;
568                         }
569                 }
570                 
571                 [DefaultValue (null)]
572                 [TemplateContainer (typeof(FormView), BindingDirection.OneWay)]
573                 [PersistenceMode (PersistenceMode.InnerProperty)]
574                 [Browsable (false)]
575                 public virtual ITemplate HeaderTemplate {
576                         get { return headerTemplate; }
577                         set { headerTemplate = value; RequireBinding (); }
578                 }
579
580                 [LocalizableAttribute (true)]
581                 [WebCategoryAttribute ("Appearance")]
582                 [DefaultValueAttribute ("")]
583                 public virtual string HeaderText {
584                         get {
585                                 object ob = ViewState ["HeaderText"];
586                                 if (ob != null) return (string) ob;
587                                 return string.Empty;
588                         }
589                         set {
590                                 ViewState ["HeaderText"] = value;
591                                 RequireBinding ();
592                         }
593                 }
594                 
595                 [Category ("Layout")]
596                 [DefaultValueAttribute (HorizontalAlign.NotSet)]
597                 public virtual HorizontalAlign HorizontalAlign {
598                         get {
599                                 if (ControlStyleCreated)
600                                         return ((TableStyle) ControlStyle).HorizontalAlign;
601                                 return HorizontalAlign.NotSet;
602                         }
603                         set {
604                                 ((TableStyle) ControlStyle).HorizontalAlign = value;
605                         }
606                 }
607
608                 [DefaultValue (null)]
609                 [TemplateContainer (typeof(FormView), BindingDirection.TwoWay)]
610                 [PersistenceMode (PersistenceMode.InnerProperty)]
611                 [Browsable (false)]
612                 public virtual ITemplate InsertItemTemplate {
613                         get { return insertItemTemplate; }
614                         set { insertItemTemplate = value; RequireBinding (); }
615                 }
616
617                 [WebCategoryAttribute ("Styles")]
618                 [PersistenceMode (PersistenceMode.InnerProperty)]
619                 [NotifyParentProperty (true)]
620                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
621                 [DefaultValueAttribute (null)]
622                 public TableItemStyle InsertRowStyle {
623                         get {
624                                 if (insertRowStyle == null) {
625                                         insertRowStyle = new TableItemStyle ();
626                                         if (IsTrackingViewState)
627                                                 insertRowStyle.TrackViewState();
628                                 }
629                                 return insertRowStyle;
630                         }
631                 }
632
633                 [DefaultValue (null)]
634                 [TemplateContainer (typeof(FormView), BindingDirection.TwoWay)]
635                 [PersistenceMode (PersistenceMode.InnerProperty)]
636                 [Browsable (false)]
637                 public virtual ITemplate ItemTemplate {
638                         get { return itemTemplate; }
639                         set { itemTemplate = value; RequireBinding (); }
640                 }
641                 
642                 [BrowsableAttribute (false)]
643                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
644                 public virtual int PageCount {
645                         get {
646                                 if (pageCount != 0) return pageCount;
647                                 EnsureDataBound ();
648                                 return pageCount;
649                         }
650                 }
651
652                 [WebCategoryAttribute ("Paging")]
653                 [BindableAttribute (true, BindingDirection.OneWay)]
654                 [DefaultValueAttribute (0)]
655                 public virtual int PageIndex {
656                         get {
657                                 return pageIndex;
658                         }
659                         set {
660                                 if (pageIndex == value)
661                                         return;
662                                 pageIndex = value;
663                                 RequireBinding ();
664                         }
665                 }
666         
667                 [WebCategoryAttribute ("Paging")]
668                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
669                 [NotifyParentPropertyAttribute (true)]
670                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
671                 public virtual PagerSettings PagerSettings {
672                         get {
673                                 if (pagerSettings == null) {
674                                         pagerSettings = new PagerSettings (this);
675                                         if (IsTrackingViewState)
676                                                 ((IStateManager)pagerSettings).TrackViewState ();
677                                 }
678                                 return pagerSettings;
679                         }
680                 }
681         
682                 [WebCategoryAttribute ("Styles")]
683                 [PersistenceMode (PersistenceMode.InnerProperty)]
684                 [NotifyParentProperty (true)]
685                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
686                 public TableItemStyle PagerStyle {
687                         get {
688                                 if (pagerStyle == null) {
689                                         pagerStyle = new TableItemStyle ();
690                                         if (IsTrackingViewState)
691                                                 pagerStyle.TrackViewState();
692                                 }
693                                 return pagerStyle;
694                         }
695                 }
696                 
697                 
698                 [DefaultValue (null)]
699                 /* DataControlPagerCell isnt specified in the docs */
700                 //[TemplateContainer (typeof(DataControlPagerCell), BindingDirection.OneWay)]
701                 [PersistenceMode (PersistenceMode.InnerProperty)]
702                 [Browsable (false)]
703                 public virtual ITemplate PagerTemplate {
704                         get { return pagerTemplate; }
705                         set { pagerTemplate = value; RequireBinding (); }
706                 }
707                 
708                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
709                 [BrowsableAttribute (false)]
710                 public virtual FormViewRow Row {
711                         get {
712                                 EnsureDataBound ();
713                                 return itemRow;
714                         }
715                 }
716                 
717                 [WebCategoryAttribute ("Styles")]
718                 [PersistenceMode (PersistenceMode.InnerProperty)]
719                 [NotifyParentProperty (true)]
720                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
721                 [DefaultValue (null)]
722                 public TableItemStyle RowStyle {
723                         get {
724                                 if (rowStyle == null) {
725                                         rowStyle = new TableItemStyle ();
726                                         if (IsTrackingViewState)
727                                                 rowStyle.TrackViewState();
728                                 }
729                                 return rowStyle;
730                         }
731                 }
732
733                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
734                 [BrowsableAttribute (false)]
735                 public object SelectedValue {
736                         get { return DataKey.Value; }
737                 }
738                 
739                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
740                 [BrowsableAttribute (false)]
741                 public virtual FormViewRow TopPagerRow {
742                         get {
743                                 EnsureDataBound ();
744                                 return topPagerRow;
745                         }
746                 }
747         
748                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
749                 [BrowsableAttribute (false)]
750                 public virtual object DataItem {
751                         get {
752                                 EnsureDataBound ();
753                                 return dataItem;
754                         }
755                 }
756                 
757                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
758                 [BrowsableAttribute (false)]
759                 public int DataItemCount {
760                         get { return PageCount; }
761                 }               
762         
763                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
764                 [BrowsableAttribute (false)]
765                 public virtual int DataItemIndex {
766                         get { return PageIndex; }
767                 }
768
769                 int IDataItemContainer.DataItemIndex {
770                         get { return DataItemIndex; }
771                 }
772         
773                 int IDataItemContainer.DisplayIndex {
774                         get { return PageIndex; }
775                 }               
776         
777                 public virtual bool IsBindableType (Type type)
778                 {
779                         return type.IsPrimitive || type == typeof (string) || type == typeof (DateTime) || type == typeof (Guid) || type == typeof (Decimal);
780                 }
781                 
782                 protected override DataSourceSelectArguments CreateDataSourceSelectArguments ()
783                 {
784                         return base.CreateDataSourceSelectArguments ();
785                 }
786                 
787                 protected virtual FormViewRow CreateRow (int rowIndex, DataControlRowType rowType, DataControlRowState rowState)
788                 {
789                         FormViewRow row = new FormViewRow (rowIndex, rowType, rowState);
790                         OnItemCreated (EventArgs.Empty);
791                         return row;
792                 }
793                 
794                 void RequireBinding ()
795                 {
796                         if (Initialized) {
797                                 pageCount = -1;
798                                 RequiresDataBinding = true;
799                         }
800                 }
801                 
802                 protected virtual Table CreateTable ()
803                 {
804                         return new ContainedTable (this);
805                 }
806
807                 [MonoTODO]
808                 protected override void EnsureDataBound ()
809                 {
810                         base.EnsureDataBound ();
811                 }
812         
813                 protected override Style CreateControlStyle ()
814                 {
815                         TableStyle style = new TableStyle (ViewState);
816                         style.CellSpacing = 0;
817                         return style;
818                 }
819                 
820                 protected override int CreateChildControls (IEnumerable data, bool dataBinding)
821                 {
822                         PagedDataSource dataSource = new PagedDataSource ();
823                         dataSource.DataSource = data;
824                         dataSource.AllowPaging = AllowPaging;
825                         dataSource.PageSize = 1;
826                         dataSource.CurrentPageIndex = PageIndex;
827
828                         if (dataBinding) {
829                                 DataSourceView view = GetData ();
830                                 if (view != null && view.CanPage) {
831                                         dataSource.AllowServerPaging = true;
832                                         if (view.CanRetrieveTotalRowCount)
833                                                 dataSource.VirtualCount = SelectArguments.TotalRowCount;
834                                 }
835                         }
836
837                         pageCount = dataSource.DataSourceCount;
838                         bool showPager = AllowPaging && (pageCount > 1);
839                         
840                         Controls.Clear ();
841                         table = CreateTable ();
842                         Controls.Add (table);
843
844                         // Gets the current data item
845                         
846                         IEnumerator e = dataSource.GetEnumerator (); 
847                         dataItem = null;
848
849                         if (AllowPaging) {
850                                 if (e.MoveNext ())
851                                         dataItem = e.Current;
852                         }
853                         else
854                         for (int page = 0; e.MoveNext (); page++ )
855                                 if (page == PageIndex)
856                                         dataItem = e.Current;
857                         
858                         // Main table creation
859                         
860                         if (HeaderText.Length != 0 || headerTemplate != null) {
861                                 headerRow = CreateRow (-1, DataControlRowType.Header, DataControlRowState.Normal);
862                                 InitializeRow (headerRow);
863                                 table.Rows.Add (headerRow);
864                         }
865                         
866                         if (showPager && PagerSettings.Position == PagerPosition.Top || PagerSettings.Position == PagerPosition.TopAndBottom) {
867                                 topPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
868                                 InitializePager (topPagerRow, dataSource);
869                                 table.Rows.Add (topPagerRow);
870                         }
871
872                         if (pageCount > 0) {
873                                 DataControlRowState rstate = GetRowState ();
874                                 itemRow = CreateRow (0, DataControlRowType.DataRow, rstate);
875                                 InitializeRow (itemRow);
876                                 table.Rows.Add (itemRow);
877                                 
878                                 if (!dataBinding) {
879                                         if (CurrentMode == FormViewMode.Edit)
880                                                 oldEditValues = new DataKey (new OrderedDictionary ());
881                                         key = new DataKey (new OrderedDictionary (), DataKeyNames);
882                                 }
883                         } else {
884                                 switch (CurrentMode) {
885                                 case FormViewMode.Edit:
886                                         itemRow = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Edit);
887                                         break;
888                                 case FormViewMode.Insert:
889                                         itemRow = CreateRow (-1, DataControlRowType.DataRow, DataControlRowState.Insert);
890                                         break;
891                                 default:
892                                         itemRow = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
893                                         break;
894                                 }
895                                 table.Rows.Add (itemRow);
896                                 InitializeRow (itemRow);
897                         }
898                                 
899                         if (showPager && PagerSettings.Position == PagerPosition.Bottom || PagerSettings.Position == PagerPosition.TopAndBottom) {
900                                 bottomPagerRow = CreateRow (0, DataControlRowType.Pager, DataControlRowState.Normal);
901                                 InitializePager (bottomPagerRow, dataSource);
902                                 table.Rows.Add (bottomPagerRow);
903                         }
904
905                         if (FooterText.Length != 0 || footerTemplate != null) {
906                                 footerRow = CreateRow (-1, DataControlRowType.Footer, DataControlRowState.Normal);
907                                 InitializeRow (footerRow);
908                                 table.Rows.Add (footerRow);
909                         }
910                         
911                         if (dataBinding)
912                                 DataBind (false);
913                         
914                         return dataSource.DataSourceCount;
915                 }
916                 
917                 DataControlRowState GetRowState ()
918                 {
919                         DataControlRowState rstate = DataControlRowState.Normal;
920                         if (CurrentMode == FormViewMode.Edit) rstate |= DataControlRowState.Edit;
921                         else if (CurrentMode == FormViewMode.Insert) rstate |= DataControlRowState.Insert;
922                         return rstate;
923                 }
924                 
925                 protected virtual void InitializePager (FormViewRow row, PagedDataSource dataSource)
926                 {
927                         TableCell cell = new TableCell ();
928                         cell.ColumnSpan = 2;
929
930                         if (pagerTemplate != null)
931                                 pagerTemplate.InstantiateIn (cell);
932                         else
933                                 cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount));
934                         
935                         row.Cells.Add (cell);
936                 }
937                 
938                 protected virtual void InitializeRow (FormViewRow row)
939                 {
940                         TableCell cell = new TableCell ();
941                         
942                         if (row.RowType == DataControlRowType.DataRow)
943                         {
944                                 if ((row.RowState & DataControlRowState.Edit) != 0) {
945                                         if (editItemTemplate != null)
946                                                 editItemTemplate.InstantiateIn (cell);
947                                 } else if ((row.RowState & DataControlRowState.Insert) != 0) {
948                                         if (insertItemTemplate != null)
949                                                 insertItemTemplate.InstantiateIn (cell);
950                                 } else if (itemTemplate != null)
951                                         itemTemplate.InstantiateIn (cell);
952                         }
953                         else if (row.RowType == DataControlRowType.EmptyDataRow)
954                         {
955                                 if (emptyDataTemplate != null)
956                                         emptyDataTemplate.InstantiateIn (cell);
957                                 else
958                                         cell.Text = EmptyDataText;
959                         }
960                         else if (row.RowType == DataControlRowType.Footer)
961                         {
962                                 if (footerTemplate != null)
963                                         footerTemplate.InstantiateIn (cell);
964                                 else
965                                         cell.Text = FooterText;
966                         }
967                         else if (row.RowType == DataControlRowType.Header)
968                         {
969                                 if (headerTemplate != null)
970                                         headerTemplate.InstantiateIn (cell);
971                                 else
972                                         cell.Text = HeaderText;
973                         }
974                         cell.ColumnSpan = 2;
975                         row.Cells.Add (cell);
976                 }
977                 
978                 IOrderedDictionary CreateRowDataKey (object dataItem)
979                 {
980                         if (cachedKeyProperties == null) {
981                                 PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem);
982                                 cachedKeyProperties = new PropertyDescriptor [DataKeyNames.Length];
983                                 for (int n=0; n<DataKeyNames.Length; n++) { 
984                                         PropertyDescriptor p = props [DataKeyNames[n]];
985                                         if (p == null)
986                                                 new InvalidOperationException ("Property '" + DataKeyNames[n] + "' not found in object of type " + dataItem.GetType());
987                                         cachedKeyProperties [n] = p;
988                                 }
989                         }
990                         
991                         OrderedDictionary dic = new OrderedDictionary ();
992                         foreach (PropertyDescriptor p in cachedKeyProperties)
993                                 dic [p.Name] = p.GetValue (dataItem);
994                         return dic;
995                 }
996                 
997                 IOrderedDictionary GetRowValues (bool includePrimaryKey)
998                 {
999                         OrderedDictionary dic = new OrderedDictionary ();
1000                         ExtractRowValues (dic, includePrimaryKey);
1001                         return dic;
1002                 }
1003                 
1004                 protected virtual void ExtractRowValues (IOrderedDictionary fieldValues, bool includeKeys)
1005                 {
1006                         if (Row == null)
1007                                 return;
1008
1009                         DataControlRowState rowState = Row.RowState;
1010                         IBindableTemplate bt;
1011                         
1012                         if ((rowState & DataControlRowState.Insert) != 0)
1013                                 bt = insertItemTemplate as IBindableTemplate; 
1014                         else if ((rowState & DataControlRowState.Edit) != 0)
1015                                 bt = editItemTemplate as IBindableTemplate;
1016                         else
1017                                 return;
1018                         
1019                         if (bt != null) {
1020                                 IOrderedDictionary values = bt.ExtractValues (Row.Cells [0]);
1021                                 foreach (DictionaryEntry e in values) {
1022                                         if (includeKeys || Array.IndexOf (DataKeyNames, e.Key) == -1)
1023                                                 fieldValues [e.Key] = e.Value;
1024                                 }
1025                         }
1026                 }
1027                 
1028                 protected override HtmlTextWriterTag TagKey {
1029                         get {
1030                                 return HtmlTextWriterTag.Table;
1031                         }
1032                 }
1033                 
1034                 public sealed override void DataBind ()
1035                 {
1036                         if (CurrentMode == FormViewMode.Insert) {
1037                                 RequiresDataBinding = false;
1038                                 PerformDataBinding (new object [] { null });
1039                                 return;
1040                         }
1041                         
1042                         DataSourceView view = GetData ();
1043                         if (AllowPaging && view.CanPage) {
1044                                 SelectArguments.StartRowIndex = PageIndex;
1045                                 SelectArguments.MaximumRows = 1;
1046                                 if (view.CanRetrieveTotalRowCount)
1047                                         SelectArguments.RetrieveTotalRowCount = true;
1048                         }
1049
1050                         cachedKeyProperties = null;
1051                         base.DataBind ();
1052                         
1053                         if (pageCount > 0) {
1054                                 if (CurrentMode == FormViewMode.Edit)
1055                                         oldEditValues = new DataKey (GetRowValues (true));
1056                                 else
1057                                         oldEditValues = new DataKey (new OrderedDictionary ());
1058                                 key = new DataKey (CreateRowDataKey (dataItem), DataKeyNames);
1059                         }
1060                 }
1061                 
1062                 protected internal override void PerformDataBinding (IEnumerable data)
1063                 {
1064                         base.PerformDataBinding (data);
1065                 }
1066
1067                 protected internal virtual void PrepareControlHierarchy ()
1068                 {
1069                         if (table == null)
1070                                 return;
1071
1072                         table.Caption = Caption;
1073                         table.CaptionAlign = CaptionAlign;
1074
1075                         foreach (FormViewRow row in table.Rows) {
1076                                 switch (row.RowType) {
1077                                 case DataControlRowType.Header:
1078                                         if (headerStyle != null && !headerStyle.IsEmpty)
1079                                                 row.ControlStyle.CopyFrom (headerStyle);
1080                                         break;
1081                                 case DataControlRowType.Footer:
1082                                         if (footerStyle != null && !footerStyle.IsEmpty)
1083                                                 row.ControlStyle.CopyFrom (footerStyle);
1084                                         break;
1085                                 case DataControlRowType.Pager:
1086                                         if (pagerStyle != null && !pagerStyle.IsEmpty)
1087                                                 row.ControlStyle.CopyFrom (pagerStyle);
1088                                         break;
1089                                 case DataControlRowType.EmptyDataRow:
1090                                         if (emptyDataRowStyle != null && !emptyDataRowStyle.IsEmpty)
1091                                                 row.ControlStyle.CopyFrom (emptyDataRowStyle);
1092                                         break;
1093                                 case DataControlRowType.DataRow:
1094                                         if (rowStyle != null && !rowStyle.IsEmpty)
1095                                                 row.ControlStyle.CopyFrom (rowStyle);
1096                                         if ((row.RowState & (DataControlRowState.Edit | DataControlRowState.Insert)) != 0 && editRowStyle != null && !editRowStyle.IsEmpty)
1097                                                 row.ControlStyle.CopyFrom (editRowStyle);
1098                                         if ((row.RowState & DataControlRowState.Insert) != 0 && insertRowStyle != null && !insertRowStyle.IsEmpty)
1099                                                 row.ControlStyle.CopyFrom (insertRowStyle);
1100                                         break;
1101                                 default:
1102                                         break;
1103                                 }
1104                         }
1105                 }
1106                 
1107                 protected internal override void OnInit (EventArgs e)
1108                 {
1109                         Page.RegisterRequiresControlState (this);
1110                         base.OnInit (e);
1111                 }
1112                 
1113                 protected override bool OnBubbleEvent (object source, EventArgs e)
1114                 {
1115                         FormViewCommandEventArgs args = e as FormViewCommandEventArgs;
1116                         if (args != null) {
1117                                 OnItemCommand (args);
1118                                 ProcessEvent (args.CommandName, args.CommandArgument as string);
1119                         }
1120                         return base.OnBubbleEvent (source, e);
1121                 }
1122                 
1123                 void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
1124                 {
1125                         RaisePostBackEvent (eventArgument);
1126                 }
1127
1128                 protected virtual void RaisePostBackEvent (string eventArgument)
1129                 {
1130                         int i = eventArgument.IndexOf ('$');
1131                         if (i != -1)
1132                                 ProcessEvent (eventArgument.Substring (0, i), eventArgument.Substring (i + 1));
1133                         else
1134                                 ProcessEvent (eventArgument, null);
1135                 }
1136                 
1137                 void ProcessEvent (string eventName, string param)
1138                 {
1139                         switch (eventName)
1140                         {
1141                         case DataControlCommands.PageCommandName:
1142                                 int newIndex = -1;
1143                                 switch (param) {
1144                                 case DataControlCommands.FirstPageCommandArgument:
1145                                         newIndex = 0;
1146                                         break;
1147                                 case DataControlCommands.LastPageCommandArgument:
1148                                         newIndex = PageCount - 1;
1149                                         break;
1150                                 case DataControlCommands.NextPageCommandArgument:
1151                                         newIndex = PageIndex + 1;
1152                                         break;
1153                                 case DataControlCommands.PreviousPageCommandArgument:
1154                                         newIndex = PageIndex - 1;
1155                                         break;
1156                                 default:
1157                                         int paramIndex = 0;
1158                                         int.TryParse (param, out paramIndex);
1159                                         newIndex = paramIndex - 1;
1160                                         break;
1161                                 }
1162                                 ShowPage (newIndex);
1163                                 break;
1164                                         
1165                         case DataControlCommands.FirstPageCommandArgument:
1166                                 ShowPage (0);
1167                                 break;
1168
1169                         case DataControlCommands.LastPageCommandArgument:
1170                                 ShowPage (PageCount - 1);
1171                                 break;
1172                                         
1173                         case DataControlCommands.NextPageCommandArgument:
1174                                 if (PageIndex < PageCount - 1)
1175                                         ShowPage (PageIndex + 1);
1176                                 break;
1177
1178                         case DataControlCommands.PreviousPageCommandArgument:
1179                                 if (PageIndex > 0)
1180                                         ShowPage (PageIndex - 1);
1181                                 break;
1182                                         
1183                         case DataControlCommands.EditCommandName:
1184                                 ChangeMode (FormViewMode.Edit);
1185                                 break;
1186                                         
1187                         case DataControlCommands.NewCommandName:
1188                                 ChangeMode (FormViewMode.Insert);
1189                                 break;
1190                                         
1191                         case DataControlCommands.UpdateCommandName:
1192                                 UpdateItem (param, true);
1193                                 break;
1194                                         
1195                         case DataControlCommands.CancelCommandName:
1196                                 CancelEdit ();
1197                                 break;
1198                                         
1199                         case DataControlCommands.DeleteCommandName:
1200                                 DeleteItem ();
1201                                 break;
1202                                         
1203                         case DataControlCommands.InsertCommandName:
1204                                 InsertItem (true);
1205                                 break;
1206                         }
1207                 }
1208                 
1209                 void ShowPage (int newIndex)
1210                 {
1211                         FormViewPageEventArgs args = new FormViewPageEventArgs (newIndex);
1212                         OnPageIndexChanging (args);
1213                         if (!args.Cancel) {
1214                                 newIndex = args.NewPageIndex;
1215                                 if (newIndex < 0 || newIndex >= PageCount)
1216                                         return;
1217                                 EndRowEdit (false);
1218                                 PageIndex = newIndex;
1219                                 OnPageIndexChanged (EventArgs.Empty);
1220                         }
1221                 }
1222                 
1223                 public void ChangeMode (FormViewMode newMode)
1224                 {
1225                         FormViewModeEventArgs args = new FormViewModeEventArgs (newMode, false);
1226                         OnModeChanging (args);
1227                         if (!args.Cancel) {
1228                                 CurrentMode = args.NewMode;
1229                                 OnModeChanged (EventArgs.Empty);
1230                                 RequireBinding ();
1231                         }
1232                 }
1233                 
1234                 void CancelEdit ()
1235                 {
1236                         FormViewModeEventArgs args = new FormViewModeEventArgs (FormViewMode.ReadOnly, true);
1237                         OnModeChanging (args);
1238                         if (!args.Cancel) {
1239                                 EndRowEdit ();
1240                         }
1241                 }
1242
1243                 public virtual void UpdateItem (bool causesValidation)
1244                 {
1245                         UpdateItem (null, causesValidation);
1246                 }
1247                 
1248                 void UpdateItem (string param, bool causesValidation)
1249                 {
1250                         if (causesValidation)
1251                                 Page.Validate ();
1252                         
1253                         if (CurrentMode != FormViewMode.Edit) throw new NotSupportedException ();
1254                         
1255                         currentEditOldValues = oldEditValues.Values;
1256                         currentEditRowKeys = DataKey.Values;
1257                         currentEditNewValues = GetRowValues (false);
1258                         
1259                         FormViewUpdateEventArgs args = new FormViewUpdateEventArgs (param, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1260                         OnItemUpdating (args);
1261                         if (!args.Cancel) {
1262                                 DataSourceView view = GetData ();
1263                                 if (view == null)
1264                                         throw new HttpException ("The DataSourceView associated to data bound control was null");
1265                                 if (view.CanUpdate)
1266                                         view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback));
1267                         }
1268                         else
1269                                 EndRowEdit ();
1270                 }
1271
1272                 bool UpdateCallback (int recordsAffected, Exception exception)
1273                 {
1274                         FormViewUpdatedEventArgs dargs = new FormViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1275                         OnItemUpdated (dargs);
1276
1277                         if (!dargs.KeepInEditMode)                              
1278                                 EndRowEdit ();
1279
1280                         return dargs.ExceptionHandled;
1281                 }
1282
1283                 public virtual void InsertItem (bool causesValidation)
1284                 {
1285                         InsertItem (null, causesValidation);
1286                 }
1287                 
1288                 void InsertItem (string param, bool causesValidation)
1289                 {
1290                         if (causesValidation)
1291                                 Page.Validate ();
1292                         
1293                         if (CurrentMode != FormViewMode.Insert) throw new NotSupportedException ();
1294                         
1295                         currentEditNewValues = GetRowValues (true);
1296                         FormViewInsertEventArgs args = new FormViewInsertEventArgs (param, currentEditNewValues);
1297                         OnItemInserting (args);
1298                         if (!args.Cancel) {
1299                                 DataSourceView view = GetData ();
1300                                 if (view == null)
1301                                         throw new HttpException ("The DataSourceView associated to data bound control was null");
1302                                 if (view.CanInsert)
1303                                         view.Insert (currentEditNewValues, new DataSourceViewOperationCallback (InsertCallback));
1304                         }
1305                         else
1306                                 EndRowEdit ();
1307                 }
1308                 
1309                 bool InsertCallback (int recordsAffected, Exception exception)
1310                 {
1311                         FormViewInsertedEventArgs dargs = new FormViewInsertedEventArgs (recordsAffected, exception, currentEditNewValues);
1312                         OnItemInserted (dargs);
1313
1314                         if (!dargs.KeepInInsertMode)                            
1315                                 EndRowEdit ();
1316
1317                         return dargs.ExceptionHandled;
1318                 }
1319
1320                 public virtual void DeleteItem ()
1321                 {
1322                         currentEditRowKeys = DataKey.Values;
1323                         currentEditNewValues = GetRowValues (true);
1324                         
1325                         FormViewDeleteEventArgs args = new FormViewDeleteEventArgs (PageIndex, currentEditRowKeys, currentEditNewValues);
1326                         OnItemDeleting (args);
1327
1328                         if (!args.Cancel) {
1329                                 if (PageIndex == PageCount - 1)
1330                                         PageIndex --;
1331                                         
1332                                 RequireBinding ();
1333                                         
1334                                 DataSourceView view = GetData ();
1335                                 if (view != null && view.CanDelete)
1336                                         view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
1337                                 else {
1338                                         FormViewDeletedEventArgs dargs = new FormViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
1339                                         OnItemDeleted (dargs);
1340                                 }
1341                         }
1342                 }
1343
1344                 bool DeleteCallback (int recordsAffected, Exception exception)
1345                 {
1346                         FormViewDeletedEventArgs dargs = new FormViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues);
1347                         OnItemDeleted (dargs);
1348                         return dargs.ExceptionHandled;
1349                 }
1350                 
1351                 void EndRowEdit ()
1352                 {
1353                         EndRowEdit (true);
1354                 }
1355
1356                 void EndRowEdit (bool switchToDefaultMode) 
1357                 {
1358                         if (switchToDefaultMode)
1359                                 ChangeMode (DefaultMode);
1360                         oldEditValues = new DataKey (new OrderedDictionary ());
1361                         currentEditRowKeys = null;
1362                         currentEditOldValues = null;
1363                         currentEditNewValues = null;
1364                         RequireBinding ();
1365                 }
1366
1367                 protected internal override void LoadControlState (object ob)
1368                 {
1369                         if (ob == null) return;
1370                         object[] state = (object[]) ob;
1371                         base.LoadControlState (state[0]);
1372                         pageIndex = (int) state[1];
1373                         pageCount = (int) state[2];
1374                         CurrentMode = (FormViewMode) state[3];
1375                         defaultMode = (FormViewMode) state[4];
1376                         dataKeyNames = (string[]) state[5];
1377                 }
1378                 
1379                 protected internal override object SaveControlState ()
1380                 {
1381                         object bstate = base.SaveControlState ();
1382                         return new object[] {
1383                                 bstate, pageIndex, pageCount, CurrentMode, defaultMode, dataKeyNames
1384                         };
1385                 }
1386                 
1387                 protected override void TrackViewState()
1388                 {
1389                         base.TrackViewState();
1390                         if (pagerSettings != null) ((IStateManager)pagerSettings).TrackViewState();
1391                         if (footerStyle != null) ((IStateManager)footerStyle).TrackViewState();
1392                         if (headerStyle != null) ((IStateManager)headerStyle).TrackViewState();
1393                         if (pagerStyle != null) ((IStateManager)pagerStyle).TrackViewState();
1394                         if (rowStyle != null) ((IStateManager)rowStyle).TrackViewState();
1395                         if (editRowStyle != null) ((IStateManager)editRowStyle).TrackViewState();
1396                         if (insertRowStyle != null) ((IStateManager)insertRowStyle).TrackViewState();
1397                         if (emptyDataRowStyle != null) ((IStateManager)emptyDataRowStyle).TrackViewState();
1398                         if (key != null) ((IStateManager)key).TrackViewState();
1399                 }
1400
1401                 protected override object SaveViewState()
1402                 {
1403                         object[] states = new object [14];
1404                         states[0] = base.SaveViewState();
1405                         states[2] = (pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState());
1406                         states[4] = (footerStyle == null ? null : ((IStateManager)footerStyle).SaveViewState());
1407                         states[5] = (headerStyle == null ? null : ((IStateManager)headerStyle).SaveViewState());
1408                         states[6] = (pagerStyle == null ? null : ((IStateManager)pagerStyle).SaveViewState());
1409                         states[7] = (rowStyle == null ? null : ((IStateManager)rowStyle).SaveViewState());
1410                         states[8] = (insertRowStyle == null ? null : ((IStateManager)insertRowStyle).SaveViewState());
1411                         states[9] = (editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState());
1412                         states[10] = (emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).SaveViewState());
1413                         states[11] = (key == null ? null : ((IStateManager)key).SaveViewState());
1414                         states[12] = (oldEditValues == null ? null : ((IStateManager)oldEditValues).SaveViewState());
1415                         
1416                         for (int i = states.Length - 1; i >= 0; i--) {
1417                                 if (states [i] != null)
1418                                         return states;
1419                         }
1420
1421                         return null;
1422                 }
1423
1424                 protected override void LoadViewState (object savedState)
1425                 {
1426                         if (savedState == null) {
1427                                 base.LoadViewState (null);
1428                                 return;
1429                         }
1430
1431                         object [] states = (object []) savedState;
1432                         
1433                         base.LoadViewState (states[0]);
1434                         EnsureChildControls ();
1435                         
1436                         if (states[2] != null) ((IStateManager)PagerSettings).LoadViewState (states[2]);
1437                         if (states[4] != null) ((IStateManager)FooterStyle).LoadViewState (states[4]);
1438                         if (states[5] != null) ((IStateManager)HeaderStyle).LoadViewState (states[5]);
1439                         if (states[6] != null) ((IStateManager)PagerStyle).LoadViewState (states[6]);
1440                         if (states[7] != null) ((IStateManager)RowStyle).LoadViewState (states[7]);
1441                         if (states[8] != null) ((IStateManager)InsertRowStyle).LoadViewState (states[8]);
1442                         if (states[9] != null) ((IStateManager)EditRowStyle).LoadViewState (states[9]);
1443                         if (states[10] != null) ((IStateManager)EmptyDataRowStyle).LoadViewState (states[10]);
1444                         if (states[11] != null && DataKey != null) ((IStateManager)DataKey).LoadViewState (states[11]);
1445                         if (states[12] != null && oldEditValues != null) ((IStateManager)oldEditValues).LoadViewState (states[12]);
1446                 }
1447                 
1448                 protected internal override void Render (HtmlTextWriter writer)
1449                 {
1450                         PrepareControlHierarchy ();
1451                         
1452                         if (table == null)
1453                                 return;
1454
1455                         table.Render (writer);
1456                 }
1457
1458                 PostBackOptions IPostBackContainer.GetPostBackOptions (IButtonControl control)
1459                 {
1460                         Control ctrl = control as Control;
1461                         return new PostBackOptions(ctrl);
1462                 }
1463
1464         }
1465 }
1466
1467 #endif