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