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