Merge pull request #4621 from alexanderkyte/strdup_env
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / DetailsView.cs
index 747329e76170a767fe4e9e3ea53f534eb4852cbc..af981d0994395f7fb944f5e24164f85185df9482 100644 (file)
@@ -4,7 +4,7 @@
 // Authors:
 //     Lluis Sanchez Gual (lluis@novell.com)
 //
-// (C) 2005 Novell, Inc (http://www.novell.com)
+// (C) 2005-2010 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -26,8 +26,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_2_0
-
 using System;
 using System.Collections;
 using System.Collections.Specialized;
@@ -40,13 +38,16 @@ using System.Reflection;
 
 namespace System.Web.UI.WebControls
 {
-       [ToolboxDataAttribute ("<{0}:DetailsView runat=\"server\" Width=\"125px\" Height=\"50px\"></{0}:DetailsView>")]\r
-       [DesignerAttribute ("System.Web.UI.Design.WebControls.DetailsViewDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.ComponentModel.Design.IDesigner")]
+       [SupportsEventValidation]
+       [ToolboxDataAttribute ("<{0}:DetailsView runat=\"server\" Width=\"125px\" Height=\"50px\"></{0}:DetailsView>")]
+       [DesignerAttribute ("System.Web.UI.Design.WebControls.DetailsViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
        [ControlValuePropertyAttribute ("SelectedValue")]
        [DefaultEventAttribute ("PageIndexChanging")]
+       [DataKeyProperty ("DataKey")]
        [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
-       public class DetailsView: CompositeDataBoundControl, ICallbackEventHandler, ICallbackContainer, IDataItemContainer
+       public class DetailsView: CompositeDataBoundControl, ICallbackEventHandler, ICallbackContainer, IDataItemContainer, INamingContainer, IPostBackEventHandler, IPostBackContainer
+               , IDataBoundItemControl, IDataBoundControl, IFieldControl
        {
                object dataItem;
                
@@ -68,10 +69,8 @@ namespace System.Web.UI.WebControls
                
                PropertyDescriptor[] cachedKeyProperties;
                readonly string[] emptyKeys = new string[0];
+               readonly string unhandledEventExceptionMessage = "The DetailsView '{0}' fired event {1} which wasn't handled.";
                
-               CommandField commandField;
-               DetailsViewRow commandRow;
-                       
                // View state
                DataControlFieldCollection columns;
                PagerSettings pagerSettings;
@@ -87,30 +86,33 @@ namespace System.Web.UI.WebControls
                TableItemStyle commandRowStyle;
                TableItemStyle fieldHeaderStyle;
                
+               IOrderedDictionary _keyTable;
                DataKey key;
                DataKey oldEditValues;
                AutoGeneratedFieldProperties[] autoFieldProperties;
                
-               private static readonly object PageIndexChangedEvent = new object();
-               private static readonly object PageIndexChangingEvent = new object();
-               private static readonly object ItemCommandEvent = new object();
-               private static readonly object ItemCreatedEvent = new object();
-               private static readonly object ItemDeletedEvent = new object();
-               private static readonly object ItemDeletingEvent = new object();
-               private static readonly object ItemInsertedEvent = new object();
-               private static readonly object ItemInsertingEvent = new object();
-               private static readonly object ModeChangingEvent = new object();
-               private static readonly object ModeChangedEvent = new object();
-               private static readonly object ItemUpdatedEvent = new object();
-               private static readonly object ItemUpdatingEvent = new object();
+               static readonly object PageIndexChangedEvent = new object();
+               static readonly object PageIndexChangingEvent = new object();
+               static readonly object ItemCommandEvent = new object();
+               static readonly object ItemCreatedEvent = new object();
+               static readonly object ItemDeletedEvent = new object();
+               static readonly object ItemDeletingEvent = new object();
+               static readonly object ItemInsertedEvent = new object();
+               static readonly object ItemInsertingEvent = new object();
+               static readonly object ModeChangingEvent = new object();
+               static readonly object ModeChangedEvent = new object();
+               static readonly object ItemUpdatedEvent = new object();
+               static readonly object ItemUpdatingEvent = new object();
                
                // Control state
                int pageIndex;
                DetailsViewMode currentMode = DetailsViewMode.ReadOnly; 
-               int pageCount = -1;
+               bool hasCurrentMode;
+               int pageCount;
                
                public DetailsView ()
                {
+                       rows = new DetailsViewRowCollection (new ArrayList ());
                }
                
                public event EventHandler PageIndexChanged {
@@ -185,8 +187,13 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                DetailsViewPageEventHandler eh = (DetailsViewPageEventHandler) Events [PageIndexChangingEvent];
-                               if (eh != null) eh (this, e);
+                               if (eh != null) {
+                                       eh (this, e);
+                                       return;
+                               }
                        }
+                       if (!IsBoundUsingDataSourceID)
+                               throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "PageIndexChanging"));
                }
                
                protected virtual void OnItemCommand (DetailsViewCommandEventArgs e)
@@ -225,16 +232,26 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                DetailsViewInsertEventHandler eh = (DetailsViewInsertEventHandler) Events [ItemInsertingEvent];
-                               if (eh != null) eh (this, e);
+                               if (eh != null) {
+                                       eh (this, e);
+                                       return;
+                               }
                        }
+                       if (!IsBoundUsingDataSourceID)
+                               throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ItemInserting"));
                }
                
                protected virtual void OnItemDeleting (DetailsViewDeleteEventArgs e)
                {
                        if (Events != null) {
                                DetailsViewDeleteEventHandler eh = (DetailsViewDeleteEventHandler) Events [ItemDeletingEvent];
-                               if (eh != null) eh (this, e);
+                               if (eh != null) {
+                                       eh (this, e);
+                                       return;
+                               }
                        }
+                       if (!IsBoundUsingDataSourceID)
+                               throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ItemDeleting"));
                }
                
                protected virtual void OnModeChanged (EventArgs e)
@@ -249,8 +266,13 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                DetailsViewModeEventHandler eh = (DetailsViewModeEventHandler) Events [ModeChangingEvent];
-                               if (eh != null) eh (this, e);
+                               if (eh != null) {
+                                       eh (this, e);
+                                       return;
+                               }
                        }
+                       if (!IsBoundUsingDataSourceID)
+                               throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ModeChanging"));
                }
                
                protected virtual void OnItemUpdated (DetailsViewUpdatedEventArgs e)
@@ -265,17 +287,53 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                DetailsViewUpdateEventHandler eh = (DetailsViewUpdateEventHandler) Events [ItemUpdatingEvent];
-                               if (eh != null) eh (this, e);
+                               if (eh != null) {
+                                       eh (this, e);
+                                       return;
+                               }
                        }
+                       if (!IsBoundUsingDataSourceID)
+                               throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ItemUpdating"));
                }
                
-               
+               DataBoundControlMode IDataBoundItemControl.Mode {
+                       get {
+                               switch (CurrentMode) {
+                                       case DetailsViewMode.ReadOnly:
+                                               return DataBoundControlMode.ReadOnly;
+
+                                       case DetailsViewMode.Edit:
+                                               return DataBoundControlMode.Edit;
+
+                                       case DetailsViewMode.Insert:
+                                               return DataBoundControlMode.Insert;
+
+                                       default:
+                                               throw new InvalidOperationException (String.Format ("Unsupported CurrentMode value '{0}'", CurrentMode));
+                               }
+                       }
+               }
+
+               IDataSource IDataBoundControl.DataSourceObject {
+                       get { return base.DataSourceObject; }
+               }
+
+               IAutoFieldGenerator IFieldControl.FieldsGenerator {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+                       
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
                [WebCategoryAttribute ("Paging")]
                [DefaultValueAttribute (false)]
-               public bool AllowPaging {
+               public virtual bool AllowPaging {
                        get {
                                object ob = ViewState ["AllowPaging"];
-                               if (ob != null) return (bool) ob;
+                               if (ob != null)
+                                       return (bool) ob;
                                return false;
                        }
                        set {
@@ -285,11 +343,11 @@ namespace System.Web.UI.WebControls
                }
                
                [DefaultValueAttribute (null)]
-           [WebCategoryAttribute ("Styles")]
+               [WebCategoryAttribute ("Styles")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [NotifyParentProperty (true)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual TableItemStyle AlternatingRowStyle {
+               public TableItemStyle AlternatingRowStyle {
                        get {
                                if (alternatingRowStyle == null) {
                                        alternatingRowStyle = new TableItemStyle ();
@@ -305,7 +363,8 @@ namespace System.Web.UI.WebControls
                public virtual bool AutoGenerateEditButton {
                        get {
                                object ob = ViewState ["AutoGenerateEditButton"];
-                               if (ob != null) return (bool) ob;
+                               if (ob != null)
+                                       return (bool) ob;
                                return false;
                        }
                        set {
@@ -319,7 +378,8 @@ namespace System.Web.UI.WebControls
                public virtual bool AutoGenerateDeleteButton {
                        get {
                                object ob = ViewState ["AutoGenerateDeleteButton"];
-                               if (ob != null) return (bool) ob;
+                               if (ob != null)
+                                       return (bool) ob;
                                return false;
                        }
                        set {
@@ -333,7 +393,8 @@ namespace System.Web.UI.WebControls
                public virtual bool AutoGenerateInsertButton {
                        get {
                                object ob = ViewState ["AutoGenerateInsertButton"];
-                               if (ob != null) return (bool) ob;
+                               if (ob != null)
+                                       return (bool) ob;
                                return false;
                        }
                        set {
@@ -347,7 +408,8 @@ namespace System.Web.UI.WebControls
                public virtual bool AutoGenerateRows {
                        get {
                                object ob = ViewState ["AutoGenerateRows"];
-                               if (ob != null) return (bool) ob;
+                               if (ob != null)
+                                       return (bool) ob;
                                return true;
                        }
                        set {
@@ -359,16 +421,15 @@ namespace System.Web.UI.WebControls
                [UrlPropertyAttribute]
                [WebCategoryAttribute ("Appearance")]
                [DefaultValueAttribute ("")]
-               [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")]
+               [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
                public virtual string BackImageUrl {
                        get {
-                               object ob = ViewState ["BackImageUrl"];
-                               if (ob != null) return (string) ob;
-                               return string.Empty;
+                               if (ControlStyleCreated)
+                                       return ((TableStyle) ControlStyle).BackImageUrl;
+                               return String.Empty;
                        }
                        set {
-                               ViewState ["BackImageUrl"] = value;
-                               RequireBinding ();
+                               ((TableStyle) ControlStyle).BackImageUrl = value;
                        }
                }
 
@@ -376,7 +437,7 @@ namespace System.Web.UI.WebControls
                [BrowsableAttribute (false)]
                public virtual DetailsViewRow BottomPagerRow {
                        get {
-                               EnsureDataBound ();
+                               EnsureChildControls ();
                                return bottomPagerRow;
                        }
                }
@@ -384,11 +445,12 @@ namespace System.Web.UI.WebControls
                [WebCategoryAttribute ("Accessibility")]
                [DefaultValueAttribute ("")]
                [LocalizableAttribute (true)]
-               public string Caption {
+               public virtual string Caption {
                        get {
                                object ob = ViewState ["Caption"];
-                               if (ob != null) return (string) ob;
-                               return string.Empty;
+                               if (ob != null)
+                                       return (string) ob;
+                               return String.Empty;
                        }
                        set {
                                ViewState ["Caption"] = value;
@@ -398,11 +460,11 @@ namespace System.Web.UI.WebControls
                
                [WebCategoryAttribute ("Accessibility")]
                [DefaultValueAttribute (TableCaptionAlign.NotSet)]
-               public virtual TableCaptionAlign CaptionAlign
-               {
+               public virtual TableCaptionAlign CaptionAlign {
                        get {
                                object o = ViewState ["CaptionAlign"];
-                               if(o != null) return (TableCaptionAlign) o;
+                               if(o != null)
+                                       return (TableCaptionAlign) o;
                                return TableCaptionAlign.NotSet;
                        }
                        set {
@@ -413,40 +475,32 @@ namespace System.Web.UI.WebControls
 
                [WebCategoryAttribute ("Layout")]
                [DefaultValueAttribute (-1)]
-               public virtual int CellPadding
-               {
+               public virtual int CellPadding {
                        get {
-                               object o = ViewState ["CellPadding"];
-                               if (o != null) return (int) o;
+                               if (ControlStyleCreated)
+                                       return ((TableStyle) ControlStyle).CellPadding;
                                return -1;
                        }
-                       set {
-                               ViewState ["CellPadding"] = value;
-                               RequireBinding ();
-                       }
+                       set { ((TableStyle) ControlStyle).CellPadding = value; }
                }
 
                [WebCategoryAttribute ("Layout")]
                [DefaultValueAttribute (0)]
-               public virtual int CellSpacing
-               {
+               public virtual int CellSpacing {
                        get {
-                               object o = ViewState ["CellSpacing"];
-                               if (o != null) return (int) o;
+                               if (ControlStyleCreated)
+                                       return ((TableStyle) ControlStyle).CellSpacing;
                                return 0;
                        }
-                       set {
-                               ViewState ["CellSpacing"] = value;
-                               RequireBinding ();
-                       }
+                       set { ((TableStyle) ControlStyle).CellSpacing = value; }
                }
                
                [DefaultValueAttribute (null)]
-           [WebCategoryAttribute ("Styles")]
+               [WebCategoryAttribute ("Styles")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [NotifyParentProperty (true)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual TableItemStyle CommandRowStyle {
+               public TableItemStyle CommandRowStyle {
                        get {
                                if (commandRowStyle == null) {
                                        commandRowStyle = new TableItemStyle ();
@@ -457,29 +511,29 @@ namespace System.Web.UI.WebControls
                        }
                }
 
-           [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]\r
-           [BrowsableAttribute (false)]\r
+               [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
+               [BrowsableAttribute (false)]
                public DetailsViewMode CurrentMode {
-                       get {
-                               return currentMode;
+                       get { return hasCurrentMode ? currentMode : DefaultMode; }
+
+                       private set {
+                               hasCurrentMode = true;
+                               currentMode = value;
                        }
                }
-       
-           [DefaultValueAttribute (DetailsViewMode.ReadOnly)]\r
-           [WebCategoryAttribute ("Behavior")]\r
+
+               DetailsViewMode defaultMode = DetailsViewMode.ReadOnly;
+               [DefaultValueAttribute (DetailsViewMode.ReadOnly)]
+               [WebCategoryAttribute ("Behavior")]
                public virtual DetailsViewMode DefaultMode {
-                       get {
-                               object o = ViewState ["DefaultMode"];
-                               if (o != null) return (DetailsViewMode) o;
-                               return DetailsViewMode.ReadOnly;
-                       }
+                       get { return defaultMode; }
                        set {
-                               ViewState ["DefaultMode"] = value;
+                               defaultMode = value;
                                RequireBinding ();
                        }
                }
        
-               [EditorAttribute ("System.Web.UI.Design.WebControls.DataControlFieldTypeEditor, 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")]
+               [EditorAttribute ("System.Web.UI.Design.WebControls.DataControlFieldTypeEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
                [MergablePropertyAttribute (false)]
                [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
                [DefaultValueAttribute (null)]
@@ -496,38 +550,57 @@ namespace System.Web.UI.WebControls
                        }
                }
 
+               string[] dataKeyNames = null;
+
                [DefaultValueAttribute (null)]
                [WebCategoryAttribute ("Data")]
                [TypeConverter (typeof(StringArrayConverter))]
-               [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")]
-               public virtual string[] DataKeyNames
-               {
+               [EditorAttribute ("System.Web.UI.Design.WebControls.DataFieldEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public virtual string[] DataKeyNames {
                        get {
-                               object o = ViewState ["DataKeyNames"];
-                               if (o != null) return (string[]) o;
-                               return emptyKeys;
+                               if (dataKeyNames == null)
+                                       return emptyKeys;
+                               else
+                                       return dataKeyNames;
                        }
                        set {
-                               ViewState ["DataKeyNames"] = value;
+                               dataKeyNames = value;
                                RequireBinding ();
                        }
                }
                
+               IOrderedDictionary KeyTable {
+                       get {
+                               if (_keyTable == null)
+                                       _keyTable = new OrderedDictionary (DataKeyNames.Length);
+                               return _keyTable;
+                       }
+               }
+
                [BrowsableAttribute (false)]
                [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
                public virtual DataKey DataKey {
                        get {
-                               EnsureDataBound ();
+                               if (key == null)
+                                       key = new DataKey (KeyTable);
                                return key;
                        }
                }
 
-           [WebCategoryAttribute ("Styles")]
+               DataKey OldEditValues {
+                       get {
+                               if (oldEditValues == null)
+                                       oldEditValues = new DataKey (new OrderedDictionary ());
+                               return oldEditValues;
+                       }
+               }
+
+               [WebCategoryAttribute ("Styles")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [NotifyParentProperty (true)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-           [DefaultValueAttribute (null)]\r
-               public virtual TableItemStyle EditRowStyle {
+               [DefaultValueAttribute (null)]
+               public TableItemStyle EditRowStyle {
                        get {
                                if (editRowStyle == null) {
                                        editRowStyle = new TableItemStyle ();
@@ -538,12 +611,12 @@ namespace System.Web.UI.WebControls
                        }
                }
                
-           [WebCategoryAttribute ("Styles")]
+               [WebCategoryAttribute ("Styles")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [NotifyParentProperty (true)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-           [DefaultValueAttribute (null)]\r
-               public virtual TableItemStyle EmptyDataRowStyle {
+               [DefaultValueAttribute (null)]
+               public TableItemStyle EmptyDataRowStyle {
                        get {
                                if (emptyDataRowStyle == null) {
                                        emptyDataRowStyle = new TableItemStyle ();
@@ -557,10 +630,10 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-           [Browsable (false)]
-               public ITemplate EmptyDataTemplate {
+               [Browsable (false)]
+               public virtual ITemplate EmptyDataTemplate {
                        get { return emptyDataTemplate; }
-                       set { emptyDataTemplate = value; RequireBinding (); }
+                       set { emptyDataTemplate = value; }
                }
                
                [LocalizableAttribute (true)]
@@ -569,8 +642,9 @@ namespace System.Web.UI.WebControls
                public virtual string EmptyDataText {
                        get {
                                object ob = ViewState ["EmptyDataText"];
-                               if (ob != null) return (string) ob;
-                               return string.Empty;
+                               if (ob != null)
+                                       return (string) ob;
+                               return String.Empty;
                        }
                        set {
                                ViewState ["EmptyDataText"] = value;
@@ -583,7 +657,8 @@ namespace System.Web.UI.WebControls
                public virtual bool EnablePagingCallbacks {
                        get {
                                object ob = ViewState ["EnablePagingCallbacks"];
-                               if (ob != null) return (bool) ob;
+                               if (ob != null)
+                                       return (bool) ob;
                                return false;
                        }
                        set {
@@ -592,12 +667,12 @@ namespace System.Web.UI.WebControls
                        }
                }
        
-           [WebCategoryAttribute ("Styles")]
+               [WebCategoryAttribute ("Styles")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [NotifyParentProperty (true)]
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual TableItemStyle FieldHeaderStyle {
+               public TableItemStyle FieldHeaderStyle {
                        get {
                                if (fieldHeaderStyle == null) {
                                        fieldHeaderStyle = new TableItemStyle ();
@@ -620,20 +695,21 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-           [Browsable (false)]
-               public ITemplate FooterTemplate {
+               [Browsable (false)]
+               public virtual ITemplate FooterTemplate {
                        get { return footerTemplate; }
-                       set { footerTemplate = value; RequireBinding (); }
+                       set { footerTemplate = value; }
                }
 
-           [LocalizableAttribute (true)]\r
-           [WebCategoryAttribute ("Appearance")]\r
-           [DefaultValueAttribute ("")]\r
-               public string FooterText {
+               [LocalizableAttribute (true)]
+               [WebCategoryAttribute ("Appearance")]
+               [DefaultValueAttribute ("")]
+               public virtual string FooterText {
                        get {
                                object ob = ViewState ["FooterText"];
-                               if (ob != null) return (string) ob;
-                               return string.Empty;
+                               if (ob != null)
+                                       return (string) ob;
+                               return String.Empty;
                        }
                        set {
                                ViewState ["FooterText"] = value;
@@ -641,12 +717,12 @@ namespace System.Web.UI.WebControls
                        }
                }
                
-           [WebCategoryAttribute ("Styles")]
+               [WebCategoryAttribute ("Styles")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [NotifyParentProperty (true)]
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual TableItemStyle FooterStyle {
+               public TableItemStyle FooterStyle {
                        get {
                                if (footerStyle == null) {
                                        footerStyle = new TableItemStyle ();
@@ -661,13 +737,11 @@ namespace System.Web.UI.WebControls
                [DefaultValueAttribute (GridLines.Both)]
                public virtual GridLines GridLines {
                        get {
-                               object ob = ViewState ["GridLines"];
-                               if (ob != null) return (GridLines) ob;
+                               if (ControlStyleCreated)
+                                       return ((TableStyle) ControlStyle).GridLines;
                                return GridLines.Both;
                        }
-                       set {
-                               ViewState ["GridLines"] = value;
-                       }
+                       set { ((TableStyle) ControlStyle).GridLines = value; }
                }
 
                [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
@@ -679,12 +753,12 @@ namespace System.Web.UI.WebControls
                        }
                }
        
-           [WebCategoryAttribute ("Styles")]
+               [WebCategoryAttribute ("Styles")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [NotifyParentProperty (true)]
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual TableItemStyle HeaderStyle {
+               public TableItemStyle HeaderStyle {
                        get {
                                if (headerStyle == null) {
                                        headerStyle = new TableItemStyle ();
@@ -698,20 +772,21 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-           [Browsable (false)]
-               public ITemplate HeaderTemplate {
+               [Browsable (false)]
+               public virtual ITemplate HeaderTemplate {
                        get { return headerTemplate; }
-                       set { headerTemplate = value; RequireBinding (); }
+                       set { headerTemplate = value; }
                }
 
-           [LocalizableAttribute (true)]\r
-           [WebCategoryAttribute ("Appearance")]\r
-           [DefaultValueAttribute ("")]\r
-               public string HeaderText {
+               [LocalizableAttribute (true)]
+               [WebCategoryAttribute ("Appearance")]
+               [DefaultValueAttribute ("")]
+               public virtual string HeaderText {
                        get {
                                object ob = ViewState ["HeaderText"];
-                               if (ob != null) return (string) ob;
-                               return string.Empty;
+                               if (ob != null)
+                                       return (string) ob;
+                               return String.Empty;
                        }
                        set {
                                ViewState ["HeaderText"] = value;
@@ -719,25 +794,23 @@ namespace System.Web.UI.WebControls
                        }
                }
                
+               [Category ("Layout")]
                [DefaultValueAttribute (HorizontalAlign.NotSet)]
                public virtual HorizontalAlign HorizontalAlign {
                        get {
-                               object ob = ViewState ["HorizontalAlign"];
-                               if (ob != null) return (HorizontalAlign) ob;
+                               if (ControlStyleCreated)
+                                       return ((TableStyle) ControlStyle).HorizontalAlign;
                                return HorizontalAlign.NotSet;
                        }
-                       set {
-                               ViewState ["HorizontalAlign"] = value;
-                               RequireBinding ();
-                       }
+                       set { ((TableStyle) ControlStyle).HorizontalAlign = value; }
                }
 
-           [WebCategoryAttribute ("Styles")]
+               [WebCategoryAttribute ("Styles")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [NotifyParentProperty (true)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-           [DefaultValueAttribute (null)]\r
-               public virtual TableItemStyle InsertRowStyle {
+               [DefaultValueAttribute (null)]
+               public TableItemStyle InsertRowStyle {
                        get {
                                if (insertRowStyle == null) {
                                        insertRowStyle = new TableItemStyle ();
@@ -750,22 +823,25 @@ namespace System.Web.UI.WebControls
                
                [BrowsableAttribute (false)]
                [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
-               public int PageCount {
-                       get {
-                               if (pageCount != -1) return pageCount;
-                               EnsureDataBound ();
-                               return pageCount;
-                       }
+               public virtual int PageCount {
+                       get { return pageCount; }
+                       private set { pageCount = value; }
                }
 
                [WebCategoryAttribute ("Paging")]
-           [BindableAttribute (true, BindingDirection.OneWay)]\r
+               [BindableAttribute (true, BindingDirection.OneWay)]
                [DefaultValueAttribute (0)]
-               public int PageIndex {
+               public virtual int PageIndex {
                        get {
+                               if (CurrentMode == DetailsViewMode.Insert)
+                                       return -1;
                                return pageIndex;
                        }
                        set {
+                               if (value < -1)
+                                       throw new ArgumentOutOfRangeException ("PageIndex must be non-negative");
+                               if (pageIndex == value || value == -1)
+                                       return;
                                pageIndex = value;
                                RequireBinding ();
                        }
@@ -775,7 +851,7 @@ namespace System.Web.UI.WebControls
                [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
                [NotifyParentPropertyAttribute (true)]
                [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
-               public PagerSettings PagerSettings {
+               public virtual PagerSettings PagerSettings {
                        get {
                                if (pagerSettings == null) {
                                        pagerSettings = new PagerSettings (this);
@@ -786,11 +862,11 @@ namespace System.Web.UI.WebControls
                        }
                }
        
-           [WebCategoryAttribute ("Styles")]
+               [WebCategoryAttribute ("Styles")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [NotifyParentProperty (true)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual TableItemStyle PagerStyle {
+               public TableItemStyle PagerStyle {
                        get {
                                if (pagerStyle == null) {
                                        pagerStyle = new TableItemStyle ();
@@ -803,29 +879,36 @@ namespace System.Web.UI.WebControls
                
                
                [DefaultValue (null)]
-               [TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)]
+               [TemplateContainer (typeof (DetailsView), BindingDirection.OneWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-           [Browsable (false)]
-               public ITemplate PagerTemplate {
+               [Browsable (false)]
+               public virtual ITemplate PagerTemplate {
                        get { return pagerTemplate; }
-                       set { pagerTemplate = value; RequireBinding (); }
+                       set { pagerTemplate = value; }
                }
                
                [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
                [BrowsableAttribute (false)]
                public virtual DetailsViewRowCollection Rows {
                        get {
-                               EnsureDataBound ();
+                               EnsureChildControls ();
                                return rows;
                        }
                }
-               
-           [WebCategoryAttribute ("Styles")]
+
+               [BrowsableAttribute(false)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               public IAutoFieldGenerator RowsGenerator {
+                       get;
+                       set;
+               }
+
+               [WebCategoryAttribute ("Styles")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [NotifyParentProperty (true)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                [DefaultValue (null)]
-               public virtual TableItemStyle RowStyle {
+               public TableItemStyle RowStyle {
                        get {
                                if (rowStyle == null) {
                                        rowStyle = new TableItemStyle ();
@@ -836,9 +919,9 @@ namespace System.Web.UI.WebControls
                        }
                }
 
-           [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]\r
+               [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
                [BrowsableAttribute (false)]
-               public virtual object SelectedValue {
+               public object SelectedValue {
                        get { return DataKey.Value; }
                }
                
@@ -846,16 +929,15 @@ namespace System.Web.UI.WebControls
                [BrowsableAttribute (false)]
                public virtual DetailsViewRow TopPagerRow {
                        get {
-                               EnsureDataBound ();
+                               EnsureChildControls ();
                                return topPagerRow;
                        }
                }
        
                [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
                [BrowsableAttribute (false)]
-               public object DataItem {
+               public virtual object DataItem {
                        get {
-                               EnsureDataBound ();
                                return dataItem;
                        }
                }
@@ -868,22 +950,55 @@ namespace System.Web.UI.WebControls
        
                [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
                [BrowsableAttribute (false)]
-               public int DataItemIndex {
+               public virtual int DataItemIndex {
                        get { return PageIndex; }
                }               
        
+               int IDataItemContainer.DisplayIndex {
+                       get { return PageIndex; }
+               }
+
+               int IDataItemContainer.DataItemIndex {
+                       get { return DataItemIndex; }
+               }
+
+               [MonoTODO ("Make use of it in the code")]
+               [DefaultValue (true)]
+               public virtual bool EnableModelValidation {
+                       get;
+                       set;
+               }
+
                public virtual bool IsBindableType (Type type)
                {
-                       return type.IsPrimitive || type == typeof(string) || type == typeof(DateTime) || type == typeof(Guid);
+                       return type.IsPrimitive || type == typeof (string) || type == typeof (DateTime) || type == typeof (Guid) || type == typeof (Decimal);
                }
                
                protected override DataSourceSelectArguments CreateDataSourceSelectArguments ()
                {
-                       return base.CreateDataSourceSelectArguments ();
+                       DataSourceSelectArguments arg = new DataSourceSelectArguments ();
+                       DataSourceView view = GetData ();
+                       if (AllowPaging && view.CanPage) {
+                               arg.StartRowIndex = PageIndex;
+                               if (view.CanRetrieveTotalRowCount) {
+                                       arg.RetrieveTotalRowCount = true;
+                                       arg.MaximumRows = 1;
+                               } else
+                                       arg.MaximumRows = -1;
+                       }
+                       return arg;
                }
                
                protected virtual ICollection CreateFieldSet (object dataItem, bool useDataSource)
                {
+                       bool autoGenerate = AutoGenerateRows;
+                       
+                       if (autoGenerate) {
+                               IAutoFieldGenerator fieldGenerator = RowsGenerator;
+                               if (fieldGenerator != null)
+                                       return fieldGenerator.GenerateFields (this);
+                       }
+                       
                        ArrayList fields = new ArrayList ();
                        
                        if (AutoGenerateRows) {
@@ -906,7 +1021,6 @@ namespace System.Web.UI.WebControls
                                field.ShowDeleteButton = AutoGenerateDeleteButton;
                                field.ShowInsertButton = AutoGenerateInsertButton;
                                fields.Add (field);
-                               commandField = field;
                        }
                        
                        return fields;
@@ -914,6 +1028,9 @@ namespace System.Web.UI.WebControls
                
                protected virtual ICollection CreateAutoGeneratedRows (object dataItem)
                {
+                       if (dataItem == null)
+                               return null;
+
                        ArrayList list = new ArrayList ();
                        autoFieldProperties = CreateAutoFieldProperties (dataItem);
                        foreach (AutoGeneratedFieldProperties props in autoFieldProperties)
@@ -928,199 +1045,230 @@ namespace System.Web.UI.WebControls
                
                AutoGeneratedFieldProperties[] CreateAutoFieldProperties (object dataItem)
                {
-                       PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem);
-                       
-                       ArrayList retVal = new ArrayList();
-                       if (props != null && props.Count > 0)
-                       {
+                       if (IsBindableType (dataItem.GetType ())) {
+                               AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
+                               ((IStateManager) field).TrackViewState ();
+                               field.Name = "Item";
+                               field.DataField = BoundField.ThisExpression;
+                               field.Type = dataItem.GetType ();
+                               return new AutoGeneratedFieldProperties [] { field };
+                       }
+
+                       PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem, false);
+
+                       if (props != null && props.Count > 0) {
+                               ArrayList retVal = new ArrayList ();
                                foreach (PropertyDescriptor current in props) {
                                        if (IsBindableType (current.PropertyType)) {
                                                AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
-                                               ((IStateManager)field).TrackViewState();
+                                               ((IStateManager) field).TrackViewState ();
                                                field.Name = current.Name;
                                                field.DataField = current.Name;
-                                               field.IsReadOnly = current.IsReadOnly;
+                                               for (int i = 0; i < DataKeyNames.Length; i++) {
+                                                       if (string.Compare (DataKeyNames [i], current.Name, StringComparison.InvariantCultureIgnoreCase) == 0) {
+                                                               field.IsReadOnly = true;
+                                                               break;
+                                                       }
+                                               }
                                                field.Type = current.PropertyType;
                                                retVal.Add (field);
                                        }
                                }
+                               if (retVal.Count > 0)
+                                       return (AutoGeneratedFieldProperties []) retVal.ToArray (typeof (AutoGeneratedFieldProperties));
                        }
-
-                       if (retVal.Count > 0)
-                               return (AutoGeneratedFieldProperties[]) retVal.ToArray (typeof(AutoGeneratedFieldProperties));
-                       else
-                               return new AutoGeneratedFieldProperties [0];
+                       throw new HttpException (String.Format ("DetailsView with id '{0}' did not have any properties or attributes from which to generate fields.  Ensure that your data source has content.", ID));
                }
                
                protected virtual DetailsViewRow CreateRow (int rowIndex, DataControlRowType rowType, DataControlRowState rowState)
                {
-                       DetailsViewRow row = new DetailsViewRow (rowIndex, rowType, rowState);
-                       OnItemCreated (EventArgs.Empty);
+                       DetailsViewRow row;
+                       if (rowType == DataControlRowType.Pager)
+                               row = new DetailsViewPagerRow (rowIndex, rowType, rowState);
+                       else
+                               row = new DetailsViewRow (rowIndex, rowType, rowState);
                        return row;
                }
                
                void RequireBinding ()
                {
-                       if (Initialized) {
+                       if (Initialized)
                                RequiresDataBinding = true;
-                               pageCount = -1;
-                       }
                }
                
                protected virtual Table CreateTable ()
                {
-                       Table table = new Table ();
-                       table.Caption = Caption;
-                       table.CaptionAlign = CaptionAlign;
-                       table.CellPadding = CellPadding;
-                       table.CellSpacing = CellSpacing;
-                       table.HorizontalAlign = HorizontalAlign;
-                       table.BackImageUrl = BackImageUrl;
-                       return table;
+                       return new ContainedTable (this);
                }
-       
-               protected override int CreateChildControls (IEnumerable data, bool dataBinding)
+
+               protected override Style CreateControlStyle ()
+               {
+                       TableStyle style = new TableStyle ();
+                       style.GridLines = GridLines.Both;
+                       style.CellSpacing = 0;
+                       return style;
+               }
+               
+               protected override int CreateChildControls (IEnumerable dataSource, bool dataBinding)
                {
-                       PagedDataSource dataSource;
+                       PagedDataSource pagedDataSource = new PagedDataSource ();
+                       pagedDataSource.DataSource = CurrentMode != DetailsViewMode.Insert ? dataSource : null;
+                       pagedDataSource.AllowPaging = AllowPaging;
+                       pagedDataSource.PageSize = 1;
+                       pagedDataSource.CurrentPageIndex = PageIndex;
 
-                       if (dataBinding) {
+                       if (dataBinding && CurrentMode != DetailsViewMode.Insert) {
                                DataSourceView view = GetData ();
-                               dataSource = new PagedDataSource ();
-                               dataSource.DataSource = data;
-                               
-                               if (AllowPaging) {
-                                       dataSource.AllowPaging = true;
-                                       dataSource.PageSize = 1;
-                                       dataSource.CurrentPageIndex = PageIndex;
-                                       if (view.CanPage) {
-                                               dataSource.AllowServerPaging = true;
-                                               if (view.CanRetrieveTotalRowCount)
-                                                       dataSource.VirtualCount = SelectArguments.TotalRowCount;
-                                               else {
-                                                       dataSource.DataSourceView = view;
-                                                       dataSource.DataSourceSelectArguments = SelectArguments;
-                                                       dataSource.SetItemCountFromPageIndex (PageIndex + PagerSettings.PageButtonCount);
-                                               }
-                                       }
-                               }
-                               
-                               pageCount = dataSource.PageCount;
-                       }
-                       else
-                       {
-                               dataSource = new PagedDataSource ();
-                               dataSource.DataSource = data;
-                               if (AllowPaging) {
-                                       dataSource.AllowPaging = true;
-                                       dataSource.PageSize = 1;
-                                       dataSource.CurrentPageIndex = PageIndex;
+                               if (view != null && view.CanPage) {
+                                       pagedDataSource.AllowServerPaging = true;
+                                       if (SelectArguments.RetrieveTotalRowCount)
+                                               pagedDataSource.VirtualCount = SelectArguments.TotalRowCount;
                                }
                        }
 
-                       bool showPager = AllowPaging && (PageCount > 1);
-                       
+                       bool showPager = AllowPaging && (pagedDataSource.PageCount > 1);
+
                        Controls.Clear ();
                        table = CreateTable ();
                        Controls.Add (table);
-                               
+                       headerRow = null;
+                       footerRow = null;
+                       topPagerRow = null;
+                       bottomPagerRow = null;
                        ArrayList list = new ArrayList ();
 
-                       if (!Page.IsPostBack)
-                               currentMode = DefaultMode;
-
-                       
                        // Gets the current data item
-                       
-                       IEnumerator e = dataSource.GetEnumerator (); 
-                       if (e.MoveNext ())
-                               dataItem = e.Current;
-                       else
-                               dataItem = null;
-                       
-                       // Creates the set of fields to show
-                       
-                       ICollection fieldCollection = CreateFieldSet (dataItem, dataBinding);
-                       DataControlField[] fields = new DataControlField [fieldCollection.Count];
-                       fieldCollection.CopyTo (fields, 0);
 
-                       foreach (DataControlField field in fields) {
-                               field.Initialize (false, this);
-                               if (EnablePagingCallbacks)
-                                       field.ValidateSupportsCallback ();
+                       if (AllowPaging) {
+                               PageCount = pagedDataSource.DataSourceCount;
+                               if (PageIndex >= PageCount && PageCount > 0)
+                                       pageIndex = pagedDataSource.CurrentPageIndex = PageCount - 1;
+                               if (pagedDataSource.DataSource != null) {
+                                       IEnumerator e = pagedDataSource.GetEnumerator ();
+                                       if (e.MoveNext ())
+                                               dataItem = e.Current;
+                               }
+                       } else {
+                               int page = 0;
+                               object lastItem = null;
+                               if (pagedDataSource.DataSource != null) {
+                                       IEnumerator e = pagedDataSource.GetEnumerator ();
+                                       for (; e.MoveNext (); page++) {
+                                               lastItem = e.Current;
+                                               if (page == PageIndex)
+                                                       dataItem = e.Current;
+                                       }
+                               }
+                               PageCount = page;
+                               if (PageIndex >= PageCount && PageCount > 0) {
+                                       pageIndex = PageCount - 1;
+                                       dataItem = lastItem;
+                               }
                        }
 
-                       // Main table creation
-                       
-                       if (HeaderText.Length != 0 || headerTemplate != null) {
+                       if (PageCount == 0 && CurrentMode != DetailsViewMode.Insert) {
+                               DetailsViewRow row = CreateEmptyRow ();
+                               if (row != null) {
+                                       table.Rows.Add (row);
+                                       list.Add (row);
+                               }
+                       } else {
+                               // Creates the set of fields to show
+
+                               ICollection fieldCollection = CreateFieldSet (dataItem, dataBinding && dataItem != null);
+                               DataControlField [] fields = new DataControlField [fieldCollection.Count];
+                               fieldCollection.CopyTo (fields, 0);
+
+                               foreach (DataControlField field in fields) {
+                                       field.Initialize (false, this);
+                                       if (EnablePagingCallbacks)
+                                               field.ValidateSupportsCallback ();
+                               }
+
+                               // Main table creation
+
                                headerRow = CreateRow (-1, DataControlRowType.Header, DataControlRowState.Normal);
-                               DataControlFieldCell cell = new DataControlFieldCell (null);
-                               cell.ColumnSpan = 2;
+                               DataControlFieldCell headerCell = new DataControlFieldCell (null);
+                               headerCell.ColumnSpan = 2;
                                if (headerTemplate != null)
-                                       headerTemplate.InstantiateIn (cell);
+                                       headerTemplate.InstantiateIn (headerCell);
+                               else if (!String.IsNullOrEmpty (HeaderText))
+                                       headerCell.Text = HeaderText;
                                else
-                                       cell.Text = HeaderText;
-                               headerRow.Cells.Add (cell);
+                                       headerRow.Visible = false;
+                               headerRow.Cells.Add (headerCell);
                                table.Rows.Add (headerRow);
-                       }
-                       
-                       if (showPager && PagerSettings.Position == PagerPosition.Top || PagerSettings.Position == PagerPosition.TopAndBottom) {
-                               topPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
-                               InitializePager (topPagerRow, dataSource);
-                               table.Rows.Add (topPagerRow);
-                       }
-                       
-                       if (dataSource.Count > 0) {
+
+                               if (showPager && PagerSettings.Position == PagerPosition.Top ||
+                                               PagerSettings.Position == PagerPosition.TopAndBottom) {
+                                       topPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
+                                       InitializePager (topPagerRow, pagedDataSource);
+                                       table.Rows.Add (topPagerRow);
+                               }
+
                                foreach (DataControlField field in fields) {
                                        DataControlRowState rstate = GetRowState (list.Count);
-                                       DetailsViewRow row = CreateRow (list.Count, DataControlRowType.DataRow, rstate);
+                                       DetailsViewRow row = CreateRow (PageIndex, DataControlRowType.DataRow, rstate);
                                        InitializeRow (row, field);
                                        table.Rows.Add (row);
                                        list.Add (row);
-
-                                       if (commandField == field)
-                                               commandRow = row;
-                               }
-                               if (!dataBinding) {
-                                       if (CurrentMode == DetailsViewMode.Edit)
-                                               oldEditValues = new DataKey (new OrderedDictionary ());
-                                       key = new DataKey (new OrderedDictionary (), DataKeyNames);
                                }
-                       } else {
-                               table.Rows.Add (CreateEmptyrRow ());
-                       }
 
-                       rows = new DetailsViewRowCollection (list);
-                       
-                       if (showPager && PagerSettings.Position == PagerPosition.Bottom || PagerSettings.Position == PagerPosition.TopAndBottom) {
-                               bottomPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
-                               InitializePager (bottomPagerRow, dataSource);
-                               table.Rows.Add (bottomPagerRow);
-                       }
-
-                       if (FooterText.Length != 0 || footerTemplate != null) {
                                footerRow = CreateRow (-1, DataControlRowType.Footer, DataControlRowState.Normal);
-                               DataControlFieldCell cell = new DataControlFieldCell (null);
-                               cell.ColumnSpan = 2;
+                               DataControlFieldCell footerCell = new DataControlFieldCell (null);
+                               footerCell.ColumnSpan = 2;
                                if (footerTemplate != null)
-                                       footerTemplate.InstantiateIn (cell);
+                                       footerTemplate.InstantiateIn (footerCell);
+                               else if (!String.IsNullOrEmpty (FooterText))
+                                       footerCell.Text = FooterText;
                                else
-                                       cell.Text = FooterText;
-                               footerRow.Cells.Add (cell);
+                                       footerRow.Visible = false;
+                               footerRow.Cells.Add (footerCell);
                                table.Rows.Add (footerRow);
+
+                               if (showPager && PagerSettings.Position == PagerPosition.Bottom ||
+                                               PagerSettings.Position == PagerPosition.TopAndBottom) {
+                                       bottomPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
+                                       InitializePager (bottomPagerRow, pagedDataSource);
+                                       table.Rows.Add (bottomPagerRow);
+                               }
                        }
                        
-                       return dataSource.DataSourceCount;
+                       rows = new DetailsViewRowCollection (list);
+
+                       if (dataBinding)
+                               DataBind (false);
+                       
+                       OnItemCreated (EventArgs.Empty);
+
+                       return PageCount;
+               }
+
+               protected override void EnsureDataBound ()
+               {
+                       if (CurrentMode == DetailsViewMode.Insert) {
+                               if (RequiresDataBinding) {
+                                       OnDataBinding (EventArgs.Empty);
+                                       RequiresDataBinding = false;
+                                       InternalPerformDataBinding (null);
+                                       MarkAsDataBound ();
+                                       OnDataBound (EventArgs.Empty);
+                               }
+                       } else
+                               base.EnsureDataBound ();
                }
                
                DataControlRowState GetRowState (int index)
                {
                        DataControlRowState rstate = (index % 2) == 0 ? DataControlRowState.Normal : DataControlRowState.Alternate;
-                       if (CurrentMode == DetailsViewMode.Edit) rstate |= DataControlRowState.Edit;
-                       else if (CurrentMode == DetailsViewMode.Insert) rstate |= DataControlRowState.Insert;
+                       if (CurrentMode == DetailsViewMode.Edit)
+                               rstate |= DataControlRowState.Edit;
+                       else if (CurrentMode == DetailsViewMode.Insert)
+                               rstate |= DataControlRowState.Insert;
                        return rstate;
                }
                
-               protected virtual void InitializePager (DetailsViewRow row, PagedDataSource dataSource)
+               protected virtual void InitializePager (DetailsViewRow row, PagedDataSource pagedDataSource)
                {
                        TableCell cell = new TableCell ();
                        cell.ColumnSpan = 2;
@@ -1128,28 +1276,35 @@ namespace System.Web.UI.WebControls
                        if (pagerTemplate != null)
                                pagerTemplate.InstantiateIn (cell);
                        else
-                               cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount));
+                               cell.Controls.Add (PagerSettings.CreatePagerControl (pagedDataSource.CurrentPageIndex, pagedDataSource.PageCount));
                        
                        row.Cells.Add (cell);
                }
                
-               DetailsViewRow CreateEmptyrRow ()
+               DetailsViewRow CreateEmptyRow ()
                {
-                       DetailsViewRow row = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
                        TableCell cell = new TableCell ();
-                       cell.ColumnSpan = 2;
-                       
+
                        if (emptyDataTemplate != null)
                                emptyDataTemplate.InstantiateIn (cell);
-                       else
+                       else if (!String.IsNullOrEmpty (EmptyDataText))
                                cell.Text = EmptyDataText;
+                       else
+                               return null;
                        
+                       DetailsViewRow row = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
                        row.Cells.Add (cell);
                        return row;
                }
                
                protected virtual void InitializeRow (DetailsViewRow row, DataControlField field)
                {
+                       if (!field.Visible) {
+                               row.Visible = false;
+                               return;
+                       }
+                       
+                       row.ContainingField = field;
                        DataControlFieldCell cell;
                        
                        if (field.ShowHeader) {
@@ -1163,25 +1318,28 @@ namespace System.Web.UI.WebControls
                                cell.ColumnSpan = 2;
                        row.Cells.Add (cell);
                        field.InitializeCell (cell, DataControlCellType.DataCell, row.RowState, row.RowIndex);
+
+                       if (CurrentMode == DetailsViewMode.Insert && !field.InsertVisible)
+                               row.Visible = false;
                }
                
-               IOrderedDictionary CreateRowDataKey (object dataItem)
+               void FillRowDataKey (object dataItem)
                {
+                       KeyTable.Clear ();
+
                        if (cachedKeyProperties == null) {
                                PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem);
                                cachedKeyProperties = new PropertyDescriptor [DataKeyNames.Length];
                                for (int n=0; n<DataKeyNames.Length; n++) { 
-                                       PropertyDescriptor p = props [DataKeyNames[n]];
+                                       PropertyDescriptor p = props.Find (DataKeyNames [n], true);
                                        if (p == null)
-                                               new InvalidOperationException ("Property '" + DataKeyNames[n] + "' not found in object of type " + dataItem.GetType());
+                                               throw new InvalidOperationException ("Property '" + DataKeyNames[n] + "' not found in object of type " + dataItem.GetType());
                                        cachedKeyProperties [n] = p;
                                }
                        }
                        
-                       OrderedDictionary dic = new OrderedDictionary ();
                        foreach (PropertyDescriptor p in cachedKeyProperties)
-                               dic [p.Name] = p.GetValue (dataItem);
-                       return dic;
+                               KeyTable [p.Name] = p.GetValue (dataItem);
                }
                
                IOrderedDictionary GetRowValues (bool includeReadOnlyFields, bool includePrimaryKey)
@@ -1191,15 +1349,16 @@ namespace System.Web.UI.WebControls
                        return dic;
                }
                
-               protected virtual void ExtractRowValues (IOrderedDictionary fieldValues, bool includeReadOnlyFields, bool includePrimaryKey)
+               protected virtual void ExtractRowValues (IOrderedDictionary fieldValues, bool includeReadOnlyFields, bool includeKeys)
                {
                        foreach (DetailsViewRow row in Rows) {
-                               if (row.Cells.Count < 1) continue;
+                               if (row.Cells.Count < 1)
+                                       continue;
                                DataControlFieldCell c = row.Cells[row.Cells.Count-1] as DataControlFieldCell;
                                if (c != null)
                                        c.ContainingField.ExtractValuesFromCell (fieldValues, c, row.RowState, includeReadOnlyFields);
                        }
-                       if (!includePrimaryKey && DataKeyNames != null)
+                       if (!includeKeys && DataKeyNames != null)
                                foreach (string key in DataKeyNames)
                                        fieldValues.Remove (key);
                }
@@ -1215,32 +1374,103 @@ namespace System.Web.UI.WebControls
                
                public sealed override void DataBind ()
                {
-                       DataSourceView view = GetData ();
-                       if (AllowPaging && view.CanPage) {
-                               SelectArguments.StartRowIndex = PageIndex;
-                               SelectArguments.MaximumRows = 1;
-                               if (view.CanRetrieveTotalRowCount)
-                                       SelectArguments.RetrieveTotalRowCount = true;
-                       }
-
                        cachedKeyProperties = null;
                        base.DataBind ();
                        
                        if (dataItem != null) {
                                if (CurrentMode == DetailsViewMode.Edit)
                                        oldEditValues = new DataKey (GetRowValues (false, true));
-                               key = new DataKey (CreateRowDataKey (dataItem), DataKeyNames);
+                               FillRowDataKey (dataItem);
+                               key = new DataKey (KeyTable);
                        }
                }
                
-               protected override void PerformDataBinding (IEnumerable data)
+               protected internal override void PerformDataBinding (IEnumerable data)
                {
                        base.PerformDataBinding (data);
                }
+
+               protected internal virtual void PrepareControlHierarchy ()
+               {
+                       if (table == null)
+                               return;
+
+                       table.Caption = Caption;
+                       table.CaptionAlign = CaptionAlign;
+
+                       foreach (DetailsViewRow row in table.Rows) {
+                               switch (row.RowType) {
+                                       case DataControlRowType.Header:
+                                               if (headerStyle != null && !headerStyle.IsEmpty)
+                                                       row.ControlStyle.CopyFrom (headerStyle);
+                                               break;
+                                       case DataControlRowType.Footer:
+                                               if (footerStyle != null && !footerStyle.IsEmpty)
+                                                       row.ControlStyle.CopyFrom (footerStyle);
+                                               break;
+                                       case DataControlRowType.Pager:
+                                               if (pagerStyle != null && !pagerStyle.IsEmpty)
+                                                       row.ControlStyle.CopyFrom (pagerStyle);
+                                               break;
+                                       case DataControlRowType.EmptyDataRow:
+                                               if (emptyDataRowStyle != null && !emptyDataRowStyle.IsEmpty)
+                                                       row.ControlStyle.CopyFrom (emptyDataRowStyle);
+                                               break;
+                                       case DataControlRowType.DataRow:
+                                               if (rowStyle != null && !rowStyle.IsEmpty)
+                                                       row.ControlStyle.CopyFrom (rowStyle);
+                                               if ((row.RowState & DataControlRowState.Alternate) != 0 && alternatingRowStyle != null && !alternatingRowStyle.IsEmpty)
+                                                       row.ControlStyle.CopyFrom (alternatingRowStyle);
+                                               break;
+                                       default:
+                                               break;
+                               }
+
+                               if (row.ContainingField is CommandField) {
+                                       if (commandRowStyle != null && !commandRowStyle.IsEmpty)
+                                               row.ControlStyle.CopyFrom (commandRowStyle);
+                               } else {
+                                       if ((row.RowState & DataControlRowState.Edit) != 0 && editRowStyle != null && !editRowStyle.IsEmpty)
+                                               row.ControlStyle.CopyFrom (editRowStyle);
+                                       if ((row.RowState & DataControlRowState.Insert) != 0) {
+                                               if (insertRowStyle != null && !insertRowStyle.IsEmpty)
+                                                       row.ControlStyle.CopyFrom (insertRowStyle);
+                                               else if (editRowStyle != null && !editRowStyle.IsEmpty)
+                                                       row.ControlStyle.CopyFrom (editRowStyle);
+                                       }
+                               }
+
+                               for (int n = 0; n < row.Cells.Count; n++) {
+                                       DataControlFieldCell fcell = row.Cells [n] as DataControlFieldCell;
+                                       if (fcell != null && fcell.ContainingField != null) {
+                                               DataControlField field = fcell.ContainingField;
+                                               if (n == 0 && field.ShowHeader) {
+                                                       if (fieldHeaderStyle != null && !fieldHeaderStyle.IsEmpty)
+                                                               fcell.ControlStyle.CopyFrom (fieldHeaderStyle);
+                                                       if (field.HeaderStyleCreated && !field.HeaderStyle.IsEmpty)
+                                                               fcell.ControlStyle.CopyFrom (field.HeaderStyle);
+                                               } else {
+                                                       if (field.ControlStyleCreated && !field.ControlStyle.IsEmpty) {
+                                                               foreach (Control c in fcell.Controls) {
+                                                                       WebControl wc = c as WebControl;
+                                                                       if (wc != null)
+                                                                               wc.ControlStyle.MergeWith (field.ControlStyle);
+                                                               }
+                                                       }
+                                                       
+                                                       if (field.ItemStyleCreated && !field.ItemStyle.IsEmpty)
+                                                               fcell.ControlStyle.CopyFrom (field.ItemStyle);
+                                               }
+                                       }
+                               }
+                       }
+               }
                
-               protected override void OnInit (EventArgs e)
+               protected internal override void OnInit (EventArgs e)
                {
-                       Page.RegisterRequiresControlState (this);
+                       Page page = Page;
+                       if (page != null)
+                               page.RegisterRequiresControlState (this);
                        base.OnInit (e);
                }
                
@@ -1259,121 +1489,155 @@ namespace System.Web.UI.WebControls
                {
                        DetailsViewCommandEventArgs args = e as DetailsViewCommandEventArgs;
                        if (args != null) {
-                               OnItemCommand (args);
-                               ProcessEvent (args.CommandName, args.CommandArgument as string);
+                               bool causesValidation = false;
+                               IButtonControl button = args.CommandSource as IButtonControl;
+                               if (button != null && button.CausesValidation) {
+                                       Page.Validate (button.ValidationGroup);
+                                       causesValidation = true;
+                               }
+                               ProcessCommand (args, causesValidation);
+                               return true;
                        }
                        return base.OnBubbleEvent (source, e);
                }
-               
+
+               void ProcessCommand (DetailsViewCommandEventArgs args, bool causesValidation) {
+                       OnItemCommand (args);
+                       ProcessEvent (args.CommandName, args.CommandArgument as string, causesValidation);
+               }
+
+               void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
+               {
+                       RaisePostBackEvent (eventArgument);
+               }
+
                // TODO: This is prolly obsolete
                protected virtual void RaisePostBackEvent (string eventArgument)
                {
+                       ValidateEvent (UniqueID, eventArgument);
                        int i = eventArgument.IndexOf ('$');
+                       CommandEventArgs arg;
                        if (i != -1)
-                               ProcessEvent (eventArgument.Substring (0, i), eventArgument.Substring (i + 1));
+                               arg = new CommandEventArgs (eventArgument.Substring (0, i), eventArgument.Substring (i + 1));
                        else
-                               ProcessEvent (eventArgument, null);
+                               arg = new CommandEventArgs (eventArgument, null);
+                       ProcessCommand (new DetailsViewCommandEventArgs (this, arg), false);
                }
-               
-               void ProcessEvent (string eventName, string param)
+
+               void ProcessEvent (string eventName, string param, bool causesValidation)
                {
-                       switch (eventName)
-                       {
-                               case "Page":
+                       switch (eventName) {
+                               case DataControlCommands.PageCommandName:
                                        int newIndex = -1;
                                        switch (param) {
-                                               case "First":
+                                               case DataControlCommands.FirstPageCommandArgument:
                                                        newIndex = 0;
                                                        break;
-                                               case "Last":
+                                               case DataControlCommands.LastPageCommandArgument:
                                                        newIndex = PageCount - 1;
                                                        break;
-                                               case "Next":
-                                                       if (PageIndex < PageCount - 1) newIndex = PageIndex + 1;
+                                               case DataControlCommands.NextPageCommandArgument:
+                                                       newIndex = PageIndex + 1;
                                                        break;
-                                               case "Prev":
-                                                       if (PageIndex > 0) newIndex = PageIndex - 1;
+                                               case DataControlCommands.PreviousPageCommandArgument:
+                                                       newIndex = PageIndex - 1;
                                                        break;
                                                default:
-                                                       newIndex = int.Parse (param) - 1;
+                                                       int paramIndex = 0;
+                                                       int.TryParse (param, out paramIndex);
+                                                       newIndex = paramIndex - 1;
                                                        break;
                                        }
-                                       ShowPage (newIndex);
+                                       SetPageIndex (newIndex);
                                        break;
                                        
-                               case "First":
-                                       ShowPage (0);
+                               case DataControlCommands.FirstPageCommandArgument:
+                                       SetPageIndex (0);
                                        break;
 
-                               case "Last":
-                                       ShowPage (PageCount - 1);
+                               case DataControlCommands.LastPageCommandArgument:
+                                       SetPageIndex (PageCount - 1);
                                        break;
                                        
-                               case "Next":
+                               case DataControlCommands.NextPageCommandArgument:
                                        if (PageIndex < PageCount - 1)
-                                               ShowPage (PageIndex + 1);
+                                               SetPageIndex (PageIndex + 1);
                                        break;
 
-                               case "Prev":
+                               case DataControlCommands.PreviousPageCommandArgument:
                                        if (PageIndex > 0)
-                                               ShowPage (PageIndex - 1);
+                                               SetPageIndex (PageIndex - 1);
                                        break;
                                        
-                               case "Edit":
-                                       ChangeMode (DetailsViewMode.Edit);
+                               case DataControlCommands.EditCommandName:
+                                       ProcessChangeMode (DetailsViewMode.Edit);
                                        break;
                                        
-                               case "New":
-                                       ChangeMode (DetailsViewMode.Insert);
+                               case DataControlCommands.NewCommandName:
+                                       ProcessChangeMode (DetailsViewMode.Insert);
                                        break;
                                        
-                               case "Update":
-                                       UpdateItem (param, true);
+                               case DataControlCommands.UpdateCommandName:
+                                       UpdateItem (param, causesValidation);
                                        break;
                                        
-                               case "Cancel":
+                               case DataControlCommands.CancelCommandName:
                                        CancelEdit ();
                                        break;
                                        
-                               case "Delete":
+                               case DataControlCommands.DeleteCommandName:
                                        DeleteItem ();
                                        break;
                                        
-                               case "Insert":
-                                       InsertItem (true);
+                               case DataControlCommands.InsertCommandName:
+                                       InsertItem (causesValidation);
                                        break;
                        }
                }
-               
-               void ShowPage (int newIndex)
+               public
+               void SetPageIndex (int index)
                {
-                       DetailsViewPageEventArgs args = new DetailsViewPageEventArgs (newIndex);
+                       DetailsViewPageEventArgs args = new DetailsViewPageEventArgs (index);
                        OnPageIndexChanging (args);
-                       if (!args.Cancel) {
-                               EndRowEdit ();
-                               PageIndex = args.NewPageIndex;
-                               OnPageIndexChanged (EventArgs.Empty);
-                       }
+
+                       if (args.Cancel || !IsBoundUsingDataSourceID)
+                               return;
+                       
+                       if (args.NewPageIndex < 0 || args.NewPageIndex >= PageCount)
+                               return;
+                       EndRowEdit (false);
+                       PageIndex = args.NewPageIndex;
+                       OnPageIndexChanged (EventArgs.Empty);
                }
                
                public void ChangeMode (DetailsViewMode newMode)
+               {
+                       CurrentMode = newMode;
+                       RequireBinding ();
+               }
+
+               void ProcessChangeMode (DetailsViewMode newMode)
                {
                        DetailsViewModeEventArgs args = new DetailsViewModeEventArgs (newMode, false);
                        OnModeChanging (args);
-                       if (!args.Cancel) {
-                               currentMode = args.NewMode;
-                               OnModeChanged (EventArgs.Empty);
-                               RequireBinding ();
-                       }
+
+                       if (args.Cancel || !IsBoundUsingDataSourceID)
+                               return;
+
+                       ChangeMode (args.NewMode);
+
+                       OnModeChanged (EventArgs.Empty);
                }
-               
+
                void CancelEdit ()
                {
                        DetailsViewModeEventArgs args = new DetailsViewModeEventArgs (DetailsViewMode.ReadOnly, true);
                        OnModeChanging (args);
-                       if (!args.Cancel) {
-                               EndRowEdit ();
-                       }
+
+                       if (args.Cancel || !IsBoundUsingDataSourceID)
+                               return;
+
+                       EndRowEdit ();
                }
 
                public virtual void UpdateItem (bool causesValidation)
@@ -1383,27 +1647,30 @@ namespace System.Web.UI.WebControls
                
                void UpdateItem (string param, bool causesValidation)
                {
-                       if (causesValidation)
-                               Page.Validate ();
-                       
-                       if (currentMode != DetailsViewMode.Edit) throw new NotSupportedException ();
+                       if (causesValidation && Page != null && !Page.IsValid)
+                               return;
                        
-                       currentEditOldValues = oldEditValues.Values;
+                       if (CurrentMode != DetailsViewMode.Edit)
+                               throw new HttpException ();
+
+                       currentEditOldValues = OldEditValues.Values;
 
                        currentEditRowKeys = DataKey.Values;
                        currentEditNewValues = GetRowValues (false, false);
                        
                        DetailsViewUpdateEventArgs args = new DetailsViewUpdateEventArgs (param, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
                        OnItemUpdating (args);
-                       if (!args.Cancel) {
-                               DataSourceView view = GetData ();
-                               if (view == null) throw new HttpException ("The DataSourceView associated to data bound control was null");
-                               view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback));
-                       } else
-                               EndRowEdit ();
+
+                       if (args.Cancel || !IsBoundUsingDataSourceID)
+                               return;
+                       
+                       DataSourceView view = GetData ();
+                       if (view == null)
+                               throw new HttpException ("The DataSourceView associated to data bound control was null");
+                       view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback));
                }
 
-        bool UpdateCallback (int recordsAffected, Exception exception)
+               bool UpdateCallback (int recordsAffected, Exception exception)
                {
                        DetailsViewUpdatedEventArgs dargs = new DetailsViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
                        OnItemUpdated (dargs);
@@ -1421,23 +1688,26 @@ namespace System.Web.UI.WebControls
                
                void InsertItem (string param, bool causesValidation)
                {
-                       if (causesValidation)
-                               Page.Validate ();
+                       if (causesValidation && Page != null && !Page.IsValid)
+                               return;
                        
-                       if (currentMode != DetailsViewMode.Insert) throw new NotSupportedException ();
+                       if (CurrentMode != DetailsViewMode.Insert)
+                               throw new HttpException ();
                        
                        currentEditNewValues = GetRowValues (false, true);
                        DetailsViewInsertEventArgs args = new DetailsViewInsertEventArgs (param, currentEditNewValues);
                        OnItemInserting (args);
-                       if (!args.Cancel) {
-                               DataSourceView view = GetData ();
-                               if (view == null) throw new HttpException ("The DataSourceView associated to data bound control was null");
-                               view.Insert (currentEditNewValues, new DataSourceViewOperationCallback (InsertCallback));
-                       } else
-                               EndRowEdit ();
+
+                       if (args.Cancel || !IsBoundUsingDataSourceID)
+                               return;
+
+                       DataSourceView view = GetData ();
+                       if (view == null)
+                               throw new HttpException ("The DataSourceView associated to data bound control was null");
+                       view.Insert (currentEditNewValues, new DataSourceViewOperationCallback (InsertCallback));
                }
                
-        bool InsertCallback (int recordsAffected, Exception exception)
+               bool InsertCallback (int recordsAffected, Exception exception)
                {
                        DetailsViewInsertedEventArgs dargs = new DetailsViewInsertedEventArgs (recordsAffected, exception, currentEditNewValues);
                        OnItemInserted (dargs);
@@ -1448,29 +1718,30 @@ namespace System.Web.UI.WebControls
                        return dargs.ExceptionHandled;
                }
 
-               public void DeleteItem ()
+               public virtual void DeleteItem ()
                {
                        currentEditRowKeys = DataKey.Values;
-                       currentEditNewValues = GetRowValues (true, true);
+                       currentEditNewValues = GetRowValues (true, false);
                        
                        DetailsViewDeleteEventArgs args = new DetailsViewDeleteEventArgs (PageIndex, currentEditRowKeys, currentEditNewValues);
                        OnItemDeleting (args);
 
-                       if (!args.Cancel) {
-                               if (PageIndex == PageCount - 1)
-                                       PageIndex --;
-                               RequireBinding ();
-                               DataSourceView view = GetData ();
-                               if (view != null)
-                                       view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
-                               else {
-                                       DetailsViewDeletedEventArgs dargs = new DetailsViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
-                                       OnItemDeleted (dargs);
-                               }
-                       }
+                       if (args.Cancel || !IsBoundUsingDataSourceID)
+                               return;
+
+                       DataSourceView view = GetData ();
+                       if (view != null)
+                               view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
+                       else {
+                               DetailsViewDeletedEventArgs dargs = new DetailsViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
+                               OnItemDeleted (dargs);
+                       }
+                       if (PageIndex > 0 && PageIndex == PageCount - 1)
+                               PageIndex --;
+                       RequireBinding ();
                }
 
-        bool DeleteCallback (int recordsAffected, Exception exception)
+               bool DeleteCallback (int recordsAffected, Exception exception)
                {
                        DetailsViewDeletedEventArgs dargs = new DetailsViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues);
                        OnItemDeleted (dargs);
@@ -1479,7 +1750,13 @@ namespace System.Web.UI.WebControls
                
                void EndRowEdit ()
                {
-                       ChangeMode (DefaultMode);
+                       EndRowEdit (true);
+               }
+
+               void EndRowEdit (bool switchToDefaultMode)
+               {
+                       if (switchToDefaultMode)
+                               ChangeMode (DefaultMode);
                        oldEditValues = new DataKey (new OrderedDictionary ());
                        currentEditRowKeys = null;
                        currentEditOldValues = null;
@@ -1487,47 +1764,74 @@ namespace System.Web.UI.WebControls
                        RequireBinding ();
                }
 
-               protected internal override void LoadControlState (object ob)
+               protected internal override void LoadControlState (object savedState)
                {
-                       if (ob == null) return;
-                       object[] state = (object[]) ob;
+                       if (savedState == null)
+                               return;
+                       object[] state = (object[]) savedState;
                        base.LoadControlState (state[0]);
                        pageIndex = (int) state[1];
                        pageCount = (int) state[2];
-                       currentMode = (DetailsViewMode) state[3];
+                       CurrentMode = (DetailsViewMode) state[3];
+                       dataKeyNames = (string[]) state[4];
+                       defaultMode = (DetailsViewMode) state[5];
+                       if (state [6] != null)
+                               ((IStateManager) DataKey).LoadViewState (state [6]);
+                       if (state [7] != null)
+                               ((IStateManager) OldEditValues).LoadViewState (state [7]);
                }
                
                protected internal override object SaveControlState ()
                {
                        object bstate = base.SaveControlState ();
                        return new object[] {
-                               bstate, pageIndex, pageCount, currentMode
+                               bstate, 
+                               pageIndex, 
+                               pageCount, 
+                               CurrentMode, 
+                               dataKeyNames, 
+                               defaultMode,
+                               (key == null ? null : ((IStateManager)key).SaveViewState()),
+                               (oldEditValues == null ? null : ((IStateManager) oldEditValues).SaveViewState ())
                        };
                }
                
                protected override void TrackViewState()
                {
                        base.TrackViewState();
-                       if (columns != null) ((IStateManager)columns).TrackViewState();
-                       if (pagerSettings != null) ((IStateManager)pagerSettings).TrackViewState();
-                       if (alternatingRowStyle != null) ((IStateManager)alternatingRowStyle).TrackViewState();
-                       if (footerStyle != null) ((IStateManager)footerStyle).TrackViewState();
-                       if (headerStyle != null) ((IStateManager)headerStyle).TrackViewState();
-                       if (pagerStyle != null) ((IStateManager)pagerStyle).TrackViewState();
-                       if (rowStyle != null) ((IStateManager)rowStyle).TrackViewState();
-                       if (editRowStyle != null) ((IStateManager)editRowStyle).TrackViewState();
-                       if (insertRowStyle != null) ((IStateManager)insertRowStyle).TrackViewState();
-                       if (emptyDataRowStyle != null) ((IStateManager)emptyDataRowStyle).TrackViewState();
-                       if (key != null) ((IStateManager)key).TrackViewState();
+                       if (columns != null)
+                               ((IStateManager)columns).TrackViewState();
+                       if (pagerSettings != null)
+                               ((IStateManager)pagerSettings).TrackViewState();
+                       if (alternatingRowStyle != null)
+                               ((IStateManager)alternatingRowStyle).TrackViewState();
+                       if (footerStyle != null)
+                               ((IStateManager)footerStyle).TrackViewState();
+                       if (headerStyle != null)
+                               ((IStateManager)headerStyle).TrackViewState();
+                       if (pagerStyle != null)
+                               ((IStateManager)pagerStyle).TrackViewState();
+                       if (rowStyle != null)
+                               ((IStateManager)rowStyle).TrackViewState();
+                       if (editRowStyle != null)
+                               ((IStateManager)editRowStyle).TrackViewState();
+                       if (insertRowStyle != null)
+                               ((IStateManager)insertRowStyle).TrackViewState();
+                       if (emptyDataRowStyle != null)
+                               ((IStateManager)emptyDataRowStyle).TrackViewState();
+                       if (key != null)
+                               ((IStateManager)key).TrackViewState();
                        if (autoFieldProperties != null) {
                                foreach (IStateManager sm in autoFieldProperties)
                                        sm.TrackViewState ();
                        }
+                       if (ControlStyleCreated)
+                               ControlStyle.TrackViewState ();
                }
 
                protected override object SaveViewState()
                {
-                       object[] states = new object [14];
+                       object[] states = new object [13];
                        states[0] = base.SaveViewState();
                        states[1] = (columns == null ? null : ((IStateManager)columns).SaveViewState());
                        states[2] = (pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState());
@@ -1539,8 +1843,6 @@ namespace System.Web.UI.WebControls
                        states[8] = (insertRowStyle == null ? null : ((IStateManager)insertRowStyle).SaveViewState());
                        states[9] = (editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState());
                        states[10] = (emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).SaveViewState());
-                       states[11] = (key == null ? null : ((IStateManager)key).SaveViewState());
-                       states[12] = (oldEditValues == null ? null : ((IStateManager)oldEditValues).SaveViewState());
                        
                        if (autoFieldProperties != null) {
                                object[] data = new object [autoFieldProperties.Length];
@@ -1549,8 +1851,10 @@ namespace System.Web.UI.WebControls
                                        data [n] = ((IStateManager)autoFieldProperties [n]).SaveViewState ();
                                        if (data [n] != null) allNull = false;
                                }
-                               if (!allNull) states [13] = data;
+                               if (!allNull) states [11] = data;
                        }
+                       if (ControlStyleCreated)
+                               states [12] = ControlStyle.SaveViewState ();
 
                        for (int i = states.Length - 1; i >= 0; i--) {
                                if (states [i] != null)
@@ -1569,8 +1873,8 @@ namespace System.Web.UI.WebControls
 
                        object [] states = (object []) savedState;
                        
-                       if (states[13] != null) {
-                               object[] data = (object[]) states [13];
+                       if (states[11] != null) {
+                               object[] data = (object[]) states [11];
                                autoFieldProperties = new AutoGeneratedFieldProperties [data.Length];
                                for (int n=0; n<data.Length; n++) {
                                        IStateManager p = new AutoGeneratedFieldProperties ();
@@ -1581,7 +1885,6 @@ namespace System.Web.UI.WebControls
                        }
 
                        base.LoadViewState (states[0]);
-                       EnsureChildControls ();
                        
                        if (states[1] != null) ((IStateManager)Fields).LoadViewState (states[1]);
                        if (states[2] != null) ((IStateManager)PagerSettings).LoadViewState (states[2]);
@@ -1593,148 +1896,135 @@ namespace System.Web.UI.WebControls
                        if (states[8] != null) ((IStateManager)InsertRowStyle).LoadViewState (states[8]);
                        if (states[9] != null) ((IStateManager)EditRowStyle).LoadViewState (states[9]);
                        if (states[10] != null) ((IStateManager)EmptyDataRowStyle).LoadViewState (states[10]);
-                       if (states[11] != null) ((IStateManager)DataKey).LoadViewState (states[11]);
-                       if (states[12] != null && oldEditValues != null) ((IStateManager)oldEditValues).LoadViewState (states[12]);
+                       if (states [12] != null)
+                               ControlStyle.LoadViewState (states [12]);
                }
                
-               string ICallbackEventHandler.RaiseCallbackEvent (string eventArgs)
+               void ICallbackEventHandler.RaiseCallbackEvent (string eventArgument)
                {
-                       return RaiseCallbackEvent (eventArgs);
+                       RaiseCallbackEvent (eventArgument);
                }
                
-               protected virtual string RaiseCallbackEvent (string eventArgs)
+               protected virtual void RaiseCallbackEvent (string eventArgument)
                {
-                       string[] clientData = eventArgs.Split ('|');
-                       pageIndex = int.Parse (clientData[0]);
-                       RequireBinding ();
-                       
-                       RaisePostBackEvent (clientData[2]);
-                       EnsureDataBound ();
+                       string[] clientData = eventArgument.Split ('|');
+                       PageIndex = int.Parse (clientData[0]);
                        
+                       RaisePostBackEvent (clientData[1]);
+                       DataBind ();
+               }
+
+               string ICallbackEventHandler.GetCallbackResult ()
+               {
+                       return GetCallbackResult ();
+               }
+
+               protected virtual string GetCallbackResult ()
+               {
+                       PrepareControlHierarchy ();
+
                        StringWriter sw = new StringWriter ();
-                       sw.Write (PageIndex.ToString());
+                       sw.Write (PageIndex.ToString () + '|');
 
                        HtmlTextWriter writer = new HtmlTextWriter (sw);
                        RenderGrid (writer);
                        return sw.ToString ();
                }
-               
-               string ICallbackContainer.GetCallbackScript (IButtonControl control, string argument)
+
+               protected virtual string GetCallbackScript (IButtonControl buttonControl, string argument)
                {
-                       if (EnablePagingCallbacks)
-                               return "javascript:GridView_ClientEvent (\"" + ClientID + "\",\"" + control.CommandName + "$" + control.CommandArgument + "\"); return false;";
-                       else
+                       if (EnablePagingCallbacks) {
+                               Page page = Page;
+                               if (page != null)
+                                       page.ClientScript.RegisterForEventValidation (UniqueID, argument);
+                               return "javascript:DetailsView_ClientEvent (\"" + ClientID + "\",\"" + buttonControl.CommandName + "$" + buttonControl.CommandArgument + "\"); return false;";
+                       } else
                                return null;
                }
                
-               protected override void OnPreRender (EventArgs e)
+               string ICallbackContainer.GetCallbackScript (IButtonControl control, string argument)
+               {
+                       return GetCallbackScript (control, argument);
+               }
+
+               protected override void OnPagePreLoad (object sender, EventArgs e)
+               {
+                       base.OnPagePreLoad (sender, e);
+
+                       if (Page.IsPostBack && EnablePagingCallbacks) {
+                               int page;
+                               if (int.TryParse (Page.Request.Form [ClientID + "_Page"], out page))
+                                       PageIndex = page;
+                       }
+               }
+
+               const string onPreRenderScript = @"var {0} = new Object ();
+{0}.pageIndex = {1};
+{0}.uid = {2};
+{0}.form = {3};
+";
+               protected internal override void OnPreRender (EventArgs e)
                {
                        base.OnPreRender (e);
-                       
-                       if (EnablePagingCallbacks)
-                       {
-                               if (!Page.ClientScript.IsClientScriptIncludeRegistered (typeof(GridView), "GridView.js")) {
-                                       string url = Page.ClientScript.GetWebResourceUrl (typeof(GridView), "GridView.js");
-                                       Page.ClientScript.RegisterClientScriptInclude (typeof(GridView), "GridView.js", url);
+
+                       Page page = Page;
+                       if (EnablePagingCallbacks && page != null) {
+                               ClientScriptManager scriptManager = page.ClientScript;
+                               if (!scriptManager.IsClientScriptIncludeRegistered (typeof(DetailsView), "DetailsView.js")) {
+                                       string url = scriptManager.GetWebResourceUrl (typeof(DetailsView), "DetailsView.js");
+                                       scriptManager.RegisterClientScriptInclude (typeof(DetailsView), "DetailsView.js", url);
                                }
+                               scriptManager.RegisterHiddenField (ClientID + "_Page", PageIndex.ToString ());
                                
                                string cgrid = ClientID + "_data";
-                               string script = string.Format ("var {0} = new Object ();\n", cgrid);
-                               script += string.Format ("{0}.pageIndex = {1};\n", cgrid, ClientScriptManager.GetScriptLiteral (PageIndex));
-                               script += string.Format ("{0}.uid = {1};\n", cgrid, ClientScriptManager.GetScriptLiteral (UniqueID));
-                               Page.ClientScript.RegisterStartupScript (typeof(TreeView), this.UniqueID, script, true);
+                               string script = String.Format (onPreRenderScript,
+                                                              cgrid,
+                                                              ClientScriptManager.GetScriptLiteral (PageIndex),
+                                                              ClientScriptManager.GetScriptLiteral (UniqueID),
+                                                              page.theForm);
+                               
+                               scriptManager.RegisterStartupScript (typeof(TreeView), this.UniqueID, script, true);
                                
                                // Make sure the basic script infrastructure is rendered
-                       Page.ClientScript.GetCallbackEventReference (this, "null", "", "null");
-                               Page.ClientScript.GetPostBackClientHyperlink (this, "");
+                               scriptManager.GetCallbackEventReference (this, "null", String.Empty, "null");
+                               scriptManager.GetPostBackClientHyperlink (this, String.Empty, true);
                        }
                }
                
-               protected override void Render (HtmlTextWriter writer)
+               protected internal override void Render (HtmlTextWriter writer)
                {
+                       PrepareControlHierarchy ();
+
                        if (EnablePagingCallbacks)
-                               base.RenderBeginTag (writer);
+                               writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID + "_div");
+                       writer.RenderBeginTag (HtmlTextWriterTag.Div);
 
                        RenderGrid (writer);
-                       
-                       if (EnablePagingCallbacks)
-                               base.RenderEndTag (writer);
+
+                       writer.RenderEndTag ();
                }
                
                void RenderGrid (HtmlTextWriter writer)
                {
-                       switch (GridLines) {
-                               case GridLines.Horizontal:
-                                       writer.AddAttribute (HtmlTextWriterAttribute.Rules, "rows");
-                                       writer.AddAttribute (HtmlTextWriterAttribute.Border, "1");
-                                       break;
-                               case GridLines.Vertical:
-                                       writer.AddAttribute (HtmlTextWriterAttribute.Rules, "cols");
-                                       writer.AddAttribute (HtmlTextWriterAttribute.Border, "1");
-                                       break;
-                               case GridLines.Both:
-                                       writer.AddAttribute (HtmlTextWriterAttribute.Rules, "all");
-                                       writer.AddAttribute (HtmlTextWriterAttribute.Border, "1");
-                                       break;
-                               default:
-                                       writer.AddAttribute (HtmlTextWriterAttribute.Border, "0");
-                                       break;
-                       }
-                       
-                       writer.AddAttribute (HtmlTextWriterAttribute.Cellspacing, "0");
-                       writer.AddStyleAttribute (HtmlTextWriterStyle.BorderCollapse, "collapse");
-                       table.RenderBeginTag (writer);
-                       
-                       foreach (DetailsViewRow row in table.Rows)
-                       {
-                               switch (row.RowType) {
-                                       case DataControlRowType.Header:
-                                               if (headerStyle != null)headerStyle.AddAttributesToRender (writer, row);
-                                               break;
-                                       case DataControlRowType.Footer:
-                                               if (footerStyle != null) footerStyle.AddAttributesToRender (writer, row);
-                                               break;
-                                       case DataControlRowType.Pager:
-                                               if (pagerStyle != null) pagerStyle.AddAttributesToRender (writer, row);
-                                               break;
-                                       case DataControlRowType.EmptyDataRow:
-                                               if (emptyDataRowStyle != null) emptyDataRowStyle.AddAttributesToRender (writer, row);
-                                               break;
-                                       default:
-                                               if (rowStyle != null) rowStyle.AddAttributesToRender (writer, row);
-                                               break;
-                               }
+                       if (table == null)
+                               return;
 
-                               if ((row.RowState & DataControlRowState.Alternate) != 0 && alternatingRowStyle != null)
-                                       alternatingRowStyle.AddAttributesToRender (writer, row);
-                               if ((row.RowState & DataControlRowState.Edit) != 0 && editRowStyle != null)
-                                       editRowStyle.AddAttributesToRender (writer, row);
-                               if ((row.RowState & DataControlRowState.Insert) != 0 && insertRowStyle != null)
-                                       insertRowStyle.AddAttributesToRender (writer, row);
-                                       
-                               if (row == commandRow && commandRowStyle != null)
-                                       commandRowStyle.AddAttributesToRender (writer, row);
-                               
-                               row.RenderBeginTag (writer);
-                               
-                               for (int n=0; n<row.Cells.Count; n++) {
-                                       DataControlFieldCell fcell = row.Cells[n] as DataControlFieldCell;
-                                       if (fcell != null && fcell.ContainingField != null) {
-                                               if (n == 0 && fcell.ContainingField.ShowHeader) {
-                                                       if (fieldHeaderStyle != null)
-                                                               fieldHeaderStyle.AddAttributesToRender (writer, fcell);
-                                                       fcell.ContainingField.HeaderStyle.AddAttributesToRender (writer, fcell);
-                                               }
-                                               else
-                                                       fcell.ContainingField.ItemStyle.AddAttributesToRender (writer, fcell);
-                                       }
-                                       row.Cells[n].Render (writer);
-                               }
-                               row.RenderEndTag (writer);
-                       }
-                       table.RenderEndTag (writer);
+                       table.Render (writer);
+               }
+
+               PostBackOptions IPostBackContainer.GetPostBackOptions (IButtonControl control)
+               {
+                       if (control == null)
+                               throw new ArgumentNullException ("control");
+
+                       if (control.CausesValidation)
+                               throw new InvalidOperationException ("A button that causes validation in DetailsView '" + ID + "' is attempting to use the container GridView as the post back target.  The button should either turn off validation or use itself as the post back container.");
+
+                       PostBackOptions options = new PostBackOptions (this);
+                       options.Argument = control.CommandName + "$" + control.CommandArgument;
+                       options.RequiresJavaScriptProtocol = true;
+
+                       return options;
                }
        }
 }
-
-#endif