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