copying the latest Sys.Web.Services from trunk.
[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         [DesignerAttribute ("System.Web.UI.Design.WebControls.FormViewDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.ComponentModel.Design.IDesigner")]
44         [ControlValuePropertyAttribute ("SelectedValue")]
45         [DefaultEventAttribute ("PageIndexChanging")]
46         [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
47         [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
48         public class FormView: CompositeDataBoundControl, IDataItemContainer
49         {
50                 object dataItem;
51                 
52                 Table table;
53                 FormViewRow headerRow;
54                 FormViewRow footerRow;
55                 FormViewRow bottomPagerRow;
56                 FormViewRow topPagerRow;
57                 FormViewRow itemRow;
58                 
59                 IOrderedDictionary currentEditRowKeys;
60                 IOrderedDictionary currentEditNewValues;
61                 IOrderedDictionary currentEditOldValues;
62                 
63                 ITemplate pagerTemplate;
64                 ITemplate emptyDataTemplate;
65                 ITemplate headerTemplate;
66                 ITemplate footerTemplate;
67                 ITemplate editItemTemplate;
68                 ITemplate insertItemTemplate;
69                 ITemplate itemTemplate;
70                 
71                 PropertyDescriptor[] cachedKeyProperties;
72                 readonly string[] emptyKeys = new string[0];
73                 
74                 // View state
75                 PagerSettings pagerSettings;
76                 
77                 TableItemStyle editRowStyle;
78                 TableItemStyle insertRowStyle;
79                 TableItemStyle emptyDataRowStyle;
80                 TableItemStyle footerStyle;
81                 TableItemStyle headerStyle;
82                 TableItemStyle pagerStyle;
83                 TableItemStyle rowStyle;
84                 
85                 DataKey key;
86                 DataKey oldEditValues;
87                 int dataSourceCount;
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 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, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
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 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)]\r
368             [BrowsableAttribute (false)]\r
369                 public FormViewMode CurrentMode {
370                         get {
371                                 return currentMode;
372                         }
373                 }
374         
375             [DefaultValueAttribute (FormViewMode.ReadOnly)]\r
376             [WebCategoryAttribute ("Behavior")]\r
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, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
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 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)]\r
429                 public virtual 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)]\r
445                 public virtual 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 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 ITemplate FooterTemplate {
494                         get { return footerTemplate; }
495                         set { footerTemplate = value; RequireBinding (); }
496                 }
497
498             [LocalizableAttribute (true)]\r
499             [WebCategoryAttribute ("Appearance")]\r
500             [DefaultValueAttribute ("")]\r
501                 public 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 virtual 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 virtual 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 ITemplate HeaderTemplate {
572                         get { return headerTemplate; }
573                         set { headerTemplate = value; RequireBinding (); }
574                 }
575
576             [LocalizableAttribute (true)]\r
577             [WebCategoryAttribute ("Appearance")]\r
578             [DefaultValueAttribute ("")]\r
579                 public 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                 [DefaultValueAttribute (HorizontalAlign.NotSet)]
592                 public virtual HorizontalAlign HorizontalAlign {
593                         get {
594                                 object ob = ViewState ["HorizontalAlign"];
595                                 if (ob != null) return (HorizontalAlign) ob;
596                                 return HorizontalAlign.NotSet;
597                         }
598                         set {
599                                 ViewState ["HorizontalAlign"] = value;
600                                 RequireBinding ();
601                         }
602                 }
603
604                 [DefaultValue (null)]
605                 [TemplateContainer (typeof(FormView), BindingDirection.TwoWay)]
606                 [PersistenceMode (PersistenceMode.InnerProperty)]
607             [Browsable (false)]
608                 public ITemplate InsertItemTemplate {
609                         get { return insertItemTemplate; }
610                         set { insertItemTemplate = value; RequireBinding (); }
611                 }
612
613             [WebCategoryAttribute ("Styles")]
614                 [PersistenceMode (PersistenceMode.InnerProperty)]
615                 [NotifyParentProperty (true)]
616                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
617             [DefaultValueAttribute (null)]\r
618                 public virtual TableItemStyle InsertRowStyle {
619                         get {
620                                 if (insertRowStyle == null) {
621                                         insertRowStyle = new TableItemStyle ();
622                                         if (IsTrackingViewState)
623                                                 insertRowStyle.TrackViewState();
624                                 }
625                                 return insertRowStyle;
626                         }
627                 }
628
629                 [DefaultValue (null)]
630                 [TemplateContainer (typeof(FormView), BindingDirection.TwoWay)]
631                 [PersistenceMode (PersistenceMode.InnerProperty)]
632             [Browsable (false)]
633                 public ITemplate ItemTemplate {
634                         get { return itemTemplate; }
635                         set { itemTemplate = value; RequireBinding (); }
636                 }
637                 
638                 [BrowsableAttribute (false)]
639                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
640                 public int PageCount {
641                         get {
642                                 if (pageCount != -1) return pageCount;
643                                 EnsureDataBound ();
644                                 return pageCount;
645                         }
646                 }
647
648                 [WebCategoryAttribute ("Paging")]
649             [BindableAttribute (true, BindingDirection.OneWay)]\r
650                 [DefaultValueAttribute (0)]
651                 public int PageIndex {
652                         get {
653                                 return pageIndex;
654                         }
655                         set {
656                                 pageIndex = value;
657                                 RequireBinding ();
658                         }
659                 }
660         
661                 [WebCategoryAttribute ("Paging")]
662                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
663                 [NotifyParentPropertyAttribute (true)]
664                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
665                 public PagerSettings PagerSettings {
666                         get {
667                                 if (pagerSettings == null) {
668                                         pagerSettings = new PagerSettings (this);
669                                         if (IsTrackingViewState)
670                                                 ((IStateManager)pagerSettings).TrackViewState ();
671                                 }
672                                 return pagerSettings;
673                         }
674                 }
675         
676             [WebCategoryAttribute ("Styles")]
677                 [PersistenceMode (PersistenceMode.InnerProperty)]
678                 [NotifyParentProperty (true)]
679                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
680                 public virtual TableItemStyle PagerStyle {
681                         get {
682                                 if (pagerStyle == null) {
683                                         pagerStyle = new TableItemStyle ();
684                                         if (IsTrackingViewState)
685                                                 pagerStyle.TrackViewState();
686                                 }
687                                 return pagerStyle;
688                         }
689                 }
690                 
691                 
692                 [DefaultValue (null)]
693                 [TemplateContainer (typeof(FormView), BindingDirection.OneWay)]
694                 [PersistenceMode (PersistenceMode.InnerProperty)]
695             [Browsable (false)]
696                 public ITemplate PagerTemplate {
697                         get { return pagerTemplate; }
698                         set { pagerTemplate = value; RequireBinding (); }
699                 }
700                 
701                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]\r
702                 [BrowsableAttribute (false)]\r
703                 public FormViewRow Row {
704                         get {
705                                 EnsureDataBound ();
706                                 return itemRow;
707                         }
708                 }
709             \r
710             [WebCategoryAttribute ("Styles")]
711                 [PersistenceMode (PersistenceMode.InnerProperty)]
712                 [NotifyParentProperty (true)]
713                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
714                 [DefaultValue (null)]
715                 public virtual TableItemStyle RowStyle {
716                         get {
717                                 if (rowStyle == null) {
718                                         rowStyle = new TableItemStyle ();
719                                         if (IsTrackingViewState)
720                                                 rowStyle.TrackViewState();
721                                 }
722                                 return rowStyle;
723                         }
724                 }
725
726             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]\r
727                 [BrowsableAttribute (false)]
728                 public virtual object SelectedValue {
729                         get { return DataKey.Value; }
730                 }
731                 
732                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
733                 [BrowsableAttribute (false)]
734                 public virtual FormViewRow TopPagerRow {
735                         get {
736                                 EnsureDataBound ();
737                                 return topPagerRow;
738                         }
739                 }
740         
741                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
742                 [BrowsableAttribute (false)]
743                 public object DataItem {
744                         get {
745                                 EnsureDataBound ();
746                                 return dataItem;
747                         }
748                 }
749                 
750                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
751                 [BrowsableAttribute (false)]
752                 public int DataItemCount {
753                         get { return PageCount; }
754                 }               
755         
756                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
757                 [BrowsableAttribute (false)]
758                 public int DataItemIndex {
759                         get { return PageIndex; }
760                 }               
761         
762                 public virtual bool IsBindableType (Type type)
763                 {
764                         return type.IsPrimitive || type == typeof(string) || type == typeof(DateTime) || type == typeof(Guid);
765                 }
766                 
767                 protected override DataSourceSelectArguments CreateDataSourceSelectArguments ()
768                 {
769                         return base.CreateDataSourceSelectArguments ();
770                 }
771                 
772                 protected virtual FormViewRow CreateRow (int rowIndex, DataControlRowType rowType, DataControlRowState rowState)
773                 {
774                         FormViewRow row = new FormViewRow (rowIndex, rowType, rowState);
775                         OnItemCreated (EventArgs.Empty);
776                         return row;
777                 }
778                 
779                 void RequireBinding ()
780                 {
781                         if (Initialized) {
782                                 RequiresDataBinding = true;
783                                 pageCount = -1;
784                         }
785                 }
786                 
787                 protected virtual Table CreateTable ()
788                 {
789                         Table table = new Table ();
790                         table.Caption = Caption;
791                         table.CaptionAlign = CaptionAlign;
792                         table.CellPadding = CellPadding;
793                         table.CellSpacing = CellSpacing;
794                         table.HorizontalAlign = HorizontalAlign;
795                         table.BackImageUrl = BackImageUrl;
796                         return table;
797                 }
798         
799                 protected override int CreateChildControls (IEnumerable data, bool dataBinding)
800                 {
801                         PagedDataSource dataSource;
802
803                         if (dataBinding) {
804                                 DataSourceView view = GetData ();
805                                 dataSource = new PagedDataSource ();
806                                 dataSource.DataSource = data;
807                                 
808                                 if (AllowPaging) {
809                                         dataSource.AllowPaging = true;
810                                         dataSource.PageSize = 1;
811                                         dataSource.CurrentPageIndex = PageIndex;
812                                         if (view.CanPage) {
813                                                 dataSource.AllowServerPaging = true;
814                                                 if (view.CanRetrieveTotalRowCount)
815                                                         dataSource.VirtualCount = SelectArguments.TotalRowCount;
816                                                 else {
817                                                         dataSource.DataSourceView = view;
818                                                         dataSource.DataSourceSelectArguments = SelectArguments;
819                                                         dataSource.SetItemCountFromPageIndex (PageIndex + PagerSettings.PageButtonCount);
820                                                 }
821                                         }
822                                 }
823                                 
824                                 pageCount = dataSource.PageCount;
825                         }
826                         else
827                         {
828                                 dataSource = new PagedDataSource ();
829                                 dataSource.DataSource = data;
830                                 if (AllowPaging) {
831                                         dataSource.AllowPaging = true;
832                                         dataSource.PageSize = 1;
833                                         dataSource.CurrentPageIndex = PageIndex;
834                                 }
835                         }
836
837                         bool showPager = AllowPaging && (PageCount > 1);
838                         dataSourceCount = dataSource.Count;
839                         
840                         Controls.Clear ();
841                         table = CreateTable ();
842                         Controls.Add (table);
843                                 
844                         if (!Page.IsPostBack)
845                                 currentMode = DefaultMode;
846
847                         // Gets the current data item
848                         
849                         IEnumerator e = dataSource.GetEnumerator (); 
850                         if (e.MoveNext ())
851                                 dataItem = e.Current;
852                         else
853                                 dataItem = null;
854                         
855                         // Main table creation
856                         
857                         if (HeaderText.Length != 0 || headerTemplate != null) {
858                                 headerRow = CreateRow (-1, DataControlRowType.Header, DataControlRowState.Normal);
859                                 InitializeRow (headerRow);
860                                 table.Rows.Add (headerRow);
861                         }
862                         
863                         if (showPager && PagerSettings.Position == PagerPosition.Top || PagerSettings.Position == PagerPosition.TopAndBottom) {
864                                 topPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
865                                 InitializePager (topPagerRow, dataSource);
866                                 table.Rows.Add (topPagerRow);
867                         }
868
869                         if (dataSourceCount > 0) {
870                                 DataControlRowState rstate = GetRowState ();
871                                 itemRow = CreateRow (0, DataControlRowType.DataRow, rstate);
872                                 InitializeRow (itemRow);
873                                 table.Rows.Add (itemRow);
874                                 
875                                 if (!dataBinding) {
876                                         if (CurrentMode == FormViewMode.Edit)
877                                                 oldEditValues = new DataKey (new OrderedDictionary ());
878                                         key = new DataKey (new OrderedDictionary (), DataKeyNames);
879                                 }
880                         } else {
881                                 itemRow = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
882                                 table.Rows.Add (itemRow);
883                                 InitializeRow (itemRow);
884                         }
885                                 
886                         if (showPager && PagerSettings.Position == PagerPosition.Bottom || PagerSettings.Position == PagerPosition.TopAndBottom) {
887                                 bottomPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
888                                 InitializePager (bottomPagerRow, dataSource);
889                                 table.Rows.Add (bottomPagerRow);
890                         }
891
892                         if (FooterText.Length != 0 || footerTemplate != null) {
893                                 footerRow = CreateRow (-1, DataControlRowType.Footer, DataControlRowState.Normal);
894                                 InitializeRow (footerRow);
895                                 table.Rows.Add (footerRow);
896                         }
897                         
898                         return dataSource.DataSourceCount;
899                 }
900                 
901                 DataControlRowState GetRowState ()
902                 {
903                         DataControlRowState rstate = DataControlRowState.Normal;
904                         if (CurrentMode == FormViewMode.Edit) rstate |= DataControlRowState.Edit;
905                         else if (CurrentMode == FormViewMode.Insert) rstate |= DataControlRowState.Insert;
906                         return rstate;
907                 }
908                 
909                 protected virtual void InitializePager (FormViewRow row, PagedDataSource dataSource)
910                 {
911                         TableCell cell = new TableCell ();
912                         
913                         if (pagerTemplate != null)
914                                 pagerTemplate.InstantiateIn (cell);
915                         else
916                                 cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount));
917                         
918                         row.Cells.Add (cell);
919                 }
920                 
921                 protected virtual void InitializeRow (FormViewRow row)
922                 {
923                         TableCell cell = new TableCell ();
924                         
925                         if (row.RowType == DataControlRowType.DataRow)
926                         {
927                                 if ((row.RowState & DataControlRowState.Edit) != 0) {
928                                         if (editItemTemplate != null)
929                                                 editItemTemplate.InstantiateIn (cell);
930                                 } else if ((row.RowState & DataControlRowState.Insert) != 0) {
931                                         if (insertItemTemplate != null)
932                                                 insertItemTemplate.InstantiateIn (cell);
933                                 } else if (itemTemplate != null)
934                                         itemTemplate.InstantiateIn (cell);
935                         }
936                         else if (row.RowType == DataControlRowType.EmptyDataRow)
937                         {
938                                 if (emptyDataTemplate != null)
939                                         emptyDataTemplate.InstantiateIn (cell);
940                                 else
941                                         cell.Text = EmptyDataText;
942                         }
943                         else if (row.RowType == DataControlRowType.Footer)
944                         {
945                                 if (footerTemplate != null)
946                                         footerTemplate.InstantiateIn (cell);
947                                 else
948                                         cell.Text = FooterText;
949                         }
950                         else if (row.RowType == DataControlRowType.Header)
951                         {
952                                 if (headerTemplate != null)
953                                         headerTemplate.InstantiateIn (cell);
954                                 else
955                                         cell.Text = HeaderText;
956                         }
957                         row.Cells.Add (cell);
958                 }
959                 
960                 IOrderedDictionary CreateRowDataKey (object dataItem)
961                 {
962                         if (cachedKeyProperties == null) {
963                                 PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem);
964                                 cachedKeyProperties = new PropertyDescriptor [DataKeyNames.Length];
965                                 for (int n=0; n<DataKeyNames.Length; n++) { 
966                                         PropertyDescriptor p = props [DataKeyNames[n]];
967                                         if (p == null)
968                                                 new InvalidOperationException ("Property '" + DataKeyNames[n] + "' not found in object of type " + dataItem.GetType());
969                                         cachedKeyProperties [n] = p;
970                                 }
971                         }
972                         
973                         OrderedDictionary dic = new OrderedDictionary ();
974                         foreach (PropertyDescriptor p in cachedKeyProperties)
975                                 dic [p.Name] = p.GetValue (dataItem);
976                         return dic;
977                 }
978                 
979                 IOrderedDictionary GetRowValues (bool includePrimaryKey)
980                 {
981                         OrderedDictionary dic = new OrderedDictionary ();
982                         ExtractRowValues (dic, includePrimaryKey);
983                         return dic;
984                 }
985                 
986                 protected virtual void ExtractRowValues (IOrderedDictionary fieldValues, bool includeKeys)
987                 {
988                         DataControlRowState rowState = Row.RowState;
989                         IBindableTemplate bt;
990                         
991                         if ((rowState & DataControlRowState.Insert) != 0)
992                                 bt = insertItemTemplate as IBindableTemplate; 
993                         else if ((rowState & DataControlRowState.Edit) != 0)
994                                 bt = editItemTemplate as IBindableTemplate;
995                         else
996                                 return;
997                         
998                         if (bt != null) {
999                                 IOrderedDictionary values = bt.ExtractValues (Row.Cells [0]);
1000                                 foreach (DictionaryEntry e in values) {
1001                                         if (includeKeys || Array.IndexOf (DataKeyNames, e.Key) == -1)
1002                                                 fieldValues [e.Key] = e.Value;
1003                                 }
1004                         }
1005                 }
1006                 
1007                 protected override HtmlTextWriterTag TagKey {
1008                         get {
1009                                 return HtmlTextWriterTag.Table;
1010                         }
1011                 }
1012                 
1013                 public sealed override void DataBind ()
1014                 {
1015                         DataSourceView view = GetData ();
1016                         if (AllowPaging && view.CanPage) {
1017                                 SelectArguments.StartRowIndex = PageIndex;
1018                                 SelectArguments.MaximumRows = 1;
1019                                 if (view.CanRetrieveTotalRowCount)
1020                                         SelectArguments.RetrieveTotalRowCount = true;
1021                         }
1022
1023                         cachedKeyProperties = null;
1024                         base.DataBind ();
1025                         
1026                         if (dataSourceCount > 0) {
1027                                 if (CurrentMode == FormViewMode.Edit)
1028                                         oldEditValues = new DataKey (GetRowValues (true));
1029                                 key = new DataKey (CreateRowDataKey (dataItem), DataKeyNames);
1030                         }
1031                 }
1032                 
1033                 protected override void PerformDataBinding (IEnumerable data)
1034                 {
1035                         base.PerformDataBinding (data);
1036                 }
1037                 
1038                 protected override void OnInit (EventArgs e)
1039                 {
1040                         Page.RegisterRequiresControlState (this);
1041                         base.OnInit (e);
1042                 }
1043                 
1044                 protected override void OnDataSourceViewChanged (object sender, EventArgs e)
1045                 {
1046                         base.OnDataSourceViewChanged (sender, e);
1047                         RequireBinding ();
1048                 }
1049                 
1050                 protected override bool OnBubbleEvent (object source, EventArgs e)
1051                 {
1052                         FormViewCommandEventArgs args = e as FormViewCommandEventArgs;
1053                         if (args != null) {
1054                                 OnItemCommand (args);
1055                                 ProcessEvent (args.CommandName, args.CommandArgument as string);
1056                         }
1057                         return base.OnBubbleEvent (source, e);
1058                 }
1059                 
1060                 // This is prolly obsolete
1061                 protected virtual void RaisePostBackEvent (string eventArgument)
1062                 {
1063                         int i = eventArgument.IndexOf ('$');
1064                         if (i != -1)
1065                                 ProcessEvent (eventArgument.Substring (0, i), eventArgument.Substring (i + 1));
1066                         else
1067                                 ProcessEvent (eventArgument, null);
1068                 }
1069                 
1070                 void ProcessEvent (string eventName, string param)
1071                 {
1072                         switch (eventName)
1073                         {
1074                                 case "Page":
1075                                         int newIndex = -1;
1076                                         switch (param) {
1077                                                 case "First":
1078                                                         newIndex = 0;
1079                                                         break;
1080                                                 case "Last":
1081                                                         newIndex = PageCount - 1;
1082                                                         break;
1083                                                 case "Next":
1084                                                         if (PageIndex < PageCount - 1) newIndex = PageIndex + 1;
1085                                                         break;
1086                                                 case "Prev":
1087                                                         if (PageIndex > 0) newIndex = PageIndex - 1;
1088                                                         break;
1089                                                 default:
1090                                                         newIndex = int.Parse (param) - 1;
1091                                                         break;
1092                                         }
1093                                         ShowPage (newIndex);
1094                                         break;
1095                                         
1096                                 case "First":
1097                                         ShowPage (0);
1098                                         break;
1099
1100                                 case "Last":
1101                                         ShowPage (PageCount - 1);
1102                                         break;
1103                                         
1104                                 case "Next":
1105                                         if (PageIndex < PageCount - 1)
1106                                                 ShowPage (PageIndex + 1);
1107                                         break;
1108
1109                                 case "Prev":
1110                                         if (PageIndex > 0)
1111                                                 ShowPage (PageIndex - 1);
1112                                         break;
1113                                         
1114                                 case "Edit":
1115                                         ChangeMode (FormViewMode.Edit);
1116                                         break;
1117                                         
1118                                 case "New":
1119                                         ChangeMode (FormViewMode.Insert);
1120                                         break;
1121                                         
1122                                 case "Update":
1123                                         UpdateItem (param, true);
1124                                         break;
1125                                         
1126                                 case "Cancel":
1127                                         CancelEdit ();
1128                                         break;
1129                                         
1130                                 case "Delete":
1131                                         DeleteItem ();
1132                                         break;
1133                                         
1134                                 case "Insert":
1135                                         InsertItem (true);
1136                                         break;
1137                         }
1138                 }
1139                 
1140                 void ShowPage (int newIndex)
1141                 {
1142                         FormViewPageEventArgs args = new FormViewPageEventArgs (newIndex);
1143                         OnPageIndexChanging (args);
1144                         if (!args.Cancel) {
1145                                 EndRowEdit ();
1146                                 PageIndex = args.NewPageIndex;
1147                                 OnPageIndexChanged (EventArgs.Empty);
1148                         }
1149                 }
1150                 
1151                 public void ChangeMode (FormViewMode newMode)
1152                 {
1153                         FormViewModeEventArgs args = new FormViewModeEventArgs (newMode, false);
1154                         OnModeChanging (args);
1155                         if (!args.Cancel) {
1156                                 currentMode = args.NewMode;
1157                                 OnModeChanged (EventArgs.Empty);
1158                                 RequireBinding ();
1159                         }
1160                 }
1161                 
1162                 void CancelEdit ()
1163                 {
1164                         FormViewModeEventArgs args = new FormViewModeEventArgs (FormViewMode.ReadOnly, true);
1165                         OnModeChanging (args);
1166                         if (!args.Cancel) {
1167                                 EndRowEdit ();
1168                         }
1169                 }
1170
1171                 public virtual void UpdateItem (bool causesValidation)
1172                 {
1173                         UpdateItem (null, causesValidation);
1174                 }
1175                 
1176                 void UpdateItem (string param, bool causesValidation)
1177                 {
1178                         if (causesValidation)
1179                                 Page.Validate ();
1180                         
1181                         if (currentMode != FormViewMode.Edit) throw new NotSupportedException ();
1182                         
1183                         currentEditOldValues = oldEditValues.Values;
1184                         currentEditRowKeys = DataKey.Values;
1185                         currentEditNewValues = GetRowValues (false);
1186                         
1187                         FormViewUpdateEventArgs args = new FormViewUpdateEventArgs (param, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1188                         OnItemUpdating (args);
1189                         if (!args.Cancel) {
1190                                 DataSourceView view = GetData ();
1191                                 if (view == null) throw new HttpException ("The DataSourceView associated to data bound control was null");
1192                                 view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback));
1193                         } else
1194                                 EndRowEdit ();
1195                 }
1196
1197         bool UpdateCallback (int recordsAffected, Exception exception)
1198                 {
1199                         FormViewUpdatedEventArgs dargs = new FormViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1200                         OnItemUpdated (dargs);
1201
1202                         if (!dargs.KeepInEditMode)                              
1203                                 EndRowEdit ();
1204
1205                         return dargs.ExceptionHandled;
1206                 }
1207
1208                 public virtual void InsertItem (bool causesValidation)
1209                 {
1210                         InsertItem (null, causesValidation);
1211                 }
1212                 
1213                 void InsertItem (string param, bool causesValidation)
1214                 {
1215                         if (causesValidation)
1216                                 Page.Validate ();
1217                         
1218                         if (currentMode != FormViewMode.Insert) throw new NotSupportedException ();
1219                         
1220                         currentEditNewValues = GetRowValues (true);
1221                         FormViewInsertEventArgs args = new FormViewInsertEventArgs (param, currentEditNewValues);
1222                         OnItemInserting (args);
1223                         if (!args.Cancel) {
1224                                 DataSourceView view = GetData ();
1225                                 if (view == null) throw new HttpException ("The DataSourceView associated to data bound control was null");
1226                                 view.Insert (currentEditNewValues, new DataSourceViewOperationCallback (InsertCallback));
1227                         } else
1228                                 EndRowEdit ();
1229                 }
1230                 
1231         bool InsertCallback (int recordsAffected, Exception exception)
1232                 {
1233                         FormViewInsertedEventArgs dargs = new FormViewInsertedEventArgs (recordsAffected, exception, currentEditNewValues);
1234                         OnItemInserted (dargs);
1235
1236                         if (!dargs.KeepInInsertMode)                            
1237                                 EndRowEdit ();
1238
1239                         return dargs.ExceptionHandled;
1240                 }
1241
1242                 public void DeleteItem ()
1243                 {
1244                         currentEditRowKeys = DataKey.Values;
1245                         currentEditNewValues = GetRowValues (true);
1246                         
1247                         FormViewDeleteEventArgs args = new FormViewDeleteEventArgs (PageIndex, currentEditRowKeys, currentEditNewValues);
1248                         OnItemDeleting (args);
1249
1250                         if (!args.Cancel) {
1251                                 if (PageIndex == PageCount - 1)
1252                                         PageIndex --;
1253                                         
1254                                 RequireBinding ();
1255                                         
1256                                 DataSourceView view = GetData ();
1257                                 if (view != null)
1258                                         view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
1259                                 else {
1260                                         FormViewDeletedEventArgs dargs = new FormViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
1261                                         OnItemDeleted (dargs);
1262                                 }
1263                         }
1264                 }
1265
1266         bool DeleteCallback (int recordsAffected, Exception exception)
1267                 {
1268                         FormViewDeletedEventArgs dargs = new FormViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues);
1269                         OnItemDeleted (dargs);
1270                         return dargs.ExceptionHandled;
1271                 }
1272                 
1273                 void EndRowEdit ()
1274                 {
1275                         ChangeMode (DefaultMode);
1276                         oldEditValues = new DataKey (new OrderedDictionary ());
1277                         currentEditRowKeys = null;
1278                         currentEditOldValues = null;
1279                         currentEditNewValues = null;
1280                         RequireBinding ();
1281                 }
1282
1283                 protected internal override void LoadControlState (object ob)
1284                 {
1285                         if (ob == null) return;
1286                         object[] state = (object[]) ob;
1287                         base.LoadControlState (state[0]);
1288                         pageIndex = (int) state[1];
1289                         pageCount = (int) state[2];
1290                         currentMode = (FormViewMode) state[3];
1291                 }
1292                 
1293                 protected internal override object SaveControlState ()
1294                 {
1295                         object bstate = base.SaveControlState ();
1296                         return new object[] {
1297                                 bstate, pageIndex, pageCount, currentMode
1298                         };
1299                 }
1300                 
1301                 protected override void TrackViewState()
1302                 {
1303                         base.TrackViewState();
1304                         if (pagerSettings != null) ((IStateManager)pagerSettings).TrackViewState();
1305                         if (footerStyle != null) ((IStateManager)footerStyle).TrackViewState();
1306                         if (headerStyle != null) ((IStateManager)headerStyle).TrackViewState();
1307                         if (pagerStyle != null) ((IStateManager)pagerStyle).TrackViewState();
1308                         if (rowStyle != null) ((IStateManager)rowStyle).TrackViewState();
1309                         if (editRowStyle != null) ((IStateManager)editRowStyle).TrackViewState();
1310                         if (insertRowStyle != null) ((IStateManager)insertRowStyle).TrackViewState();
1311                         if (emptyDataRowStyle != null) ((IStateManager)emptyDataRowStyle).TrackViewState();
1312                         if (key != null) ((IStateManager)key).TrackViewState();
1313                 }
1314
1315                 protected override object SaveViewState()
1316                 {
1317                         object[] states = new object [14];
1318                         states[0] = base.SaveViewState();
1319                         states[2] = (pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState());
1320                         states[4] = (footerStyle == null ? null : ((IStateManager)footerStyle).SaveViewState());
1321                         states[5] = (headerStyle == null ? null : ((IStateManager)headerStyle).SaveViewState());
1322                         states[6] = (pagerStyle == null ? null : ((IStateManager)pagerStyle).SaveViewState());
1323                         states[7] = (rowStyle == null ? null : ((IStateManager)rowStyle).SaveViewState());
1324                         states[8] = (insertRowStyle == null ? null : ((IStateManager)insertRowStyle).SaveViewState());
1325                         states[9] = (editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState());
1326                         states[10] = (emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).SaveViewState());
1327                         states[11] = (key == null ? null : ((IStateManager)key).SaveViewState());
1328                         states[12] = (oldEditValues == null ? null : ((IStateManager)oldEditValues).SaveViewState());
1329                         
1330                         for (int i = states.Length - 1; i >= 0; i--) {
1331                                 if (states [i] != null)
1332                                         return states;
1333                         }
1334
1335                         return null;
1336                 }
1337
1338                 protected override void LoadViewState (object savedState)
1339                 {
1340                         if (savedState == null) {
1341                                 base.LoadViewState (null);
1342                                 return;
1343                         }
1344
1345                         object [] states = (object []) savedState;
1346                         
1347                         base.LoadViewState (states[0]);
1348                         EnsureChildControls ();
1349                         
1350                         if (states[2] != null) ((IStateManager)PagerSettings).LoadViewState (states[2]);
1351                         if (states[4] != null) ((IStateManager)FooterStyle).LoadViewState (states[4]);
1352                         if (states[5] != null) ((IStateManager)HeaderStyle).LoadViewState (states[5]);
1353                         if (states[6] != null) ((IStateManager)PagerStyle).LoadViewState (states[6]);
1354                         if (states[7] != null) ((IStateManager)RowStyle).LoadViewState (states[7]);
1355                         if (states[8] != null) ((IStateManager)InsertRowStyle).LoadViewState (states[8]);
1356                         if (states[9] != null) ((IStateManager)EditRowStyle).LoadViewState (states[9]);
1357                         if (states[10] != null) ((IStateManager)EmptyDataRowStyle).LoadViewState (states[10]);
1358                         if (states[11] != null && DataKey != null) ((IStateManager)DataKey).LoadViewState (states[11]);
1359                         if (states[12] != null && oldEditValues != null) ((IStateManager)oldEditValues).LoadViewState (states[12]);
1360                 }
1361                 
1362                 protected override void Render (HtmlTextWriter writer)
1363                 {
1364                         switch (GridLines) {
1365                                 case GridLines.Horizontal:
1366                                         writer.AddAttribute (HtmlTextWriterAttribute.Rules, "rows");
1367                                         writer.AddAttribute (HtmlTextWriterAttribute.Border, "1");
1368                                         break;
1369                                 case GridLines.Vertical:
1370                                         writer.AddAttribute (HtmlTextWriterAttribute.Rules, "cols");
1371                                         writer.AddAttribute (HtmlTextWriterAttribute.Border, "1");
1372                                         break;
1373                                 case GridLines.Both:
1374                                         writer.AddAttribute (HtmlTextWriterAttribute.Rules, "all");
1375                                         writer.AddAttribute (HtmlTextWriterAttribute.Border, "1");
1376                                         break;
1377                                 default:
1378                                         writer.AddAttribute (HtmlTextWriterAttribute.Border, "0");
1379                                         break;
1380                         }
1381                         
1382                         writer.AddAttribute (HtmlTextWriterAttribute.Cellspacing, "0");
1383                         writer.AddStyleAttribute (HtmlTextWriterStyle.BorderCollapse, "collapse");
1384                         table.RenderBeginTag (writer);
1385                         
1386                         foreach (FormViewRow row in table.Rows)
1387                         {
1388                                 switch (row.RowType) {
1389                                         case DataControlRowType.Header:
1390                                                 if (headerStyle != null)headerStyle.AddAttributesToRender (writer, row);
1391                                                 break;
1392                                         case DataControlRowType.Footer:
1393                                                 if (footerStyle != null) footerStyle.AddAttributesToRender (writer, row);
1394                                                 break;
1395                                         case DataControlRowType.Pager:
1396                                                 if (pagerStyle != null) pagerStyle.AddAttributesToRender (writer, row);
1397                                                 break;
1398                                         case DataControlRowType.EmptyDataRow:
1399                                                 if (emptyDataRowStyle != null) emptyDataRowStyle.AddAttributesToRender (writer, row);
1400                                                 break;
1401                                         default:
1402                                                 if (rowStyle != null) rowStyle.AddAttributesToRender (writer, row);
1403                                                 break;
1404                                 }
1405
1406                                 if ((row.RowState & DataControlRowState.Edit) != 0 && editRowStyle != null)
1407                                         editRowStyle.AddAttributesToRender (writer, row);
1408                                 if ((row.RowState & DataControlRowState.Insert) != 0 && insertRowStyle != null)
1409                                         insertRowStyle.AddAttributesToRender (writer, row);
1410                                         
1411                                 row.RenderBeginTag (writer);
1412                                 
1413                                 for (int n=0; n<row.Cells.Count; n++)
1414                                         row.Cells[n].Render (writer);
1415
1416                                 row.RenderEndTag (writer);
1417                         }
1418                         table.RenderEndTag (writer);
1419                 }
1420         }
1421 }
1422
1423 #endif