New test.
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / FormView.cs
index 9fe6bfa40413d09fed939c9e1591cbccb36db68e..ea63e1d7ea26f52820143b2e5ee28bf50c3d2abb 100644 (file)
@@ -40,12 +40,13 @@ using System.Reflection;
 
 namespace System.Web.UI.WebControls
 {
-       [DesignerAttribute ("System.Web.UI.Design.WebControls.FormViewDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.ComponentModel.Design.IDesigner")]
+       [SupportsEventValidation]
+       [DesignerAttribute ("System.Web.UI.Design.WebControls.FormViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
        [ControlValuePropertyAttribute ("SelectedValue")]
        [DefaultEventAttribute ("PageIndexChanging")]
        [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
-       public class FormView: CompositeDataBoundControl, IDataItemContainer
+       public class FormView: CompositeDataBoundControl, IDataItemContainer, INamingContainer, IPostBackEventHandler, IPostBackContainer
        {
                object dataItem;
                
@@ -84,7 +85,6 @@ namespace System.Web.UI.WebControls
                
                DataKey key;
                DataKey oldEditValues;
-               int dataSourceCount;
                
                private static readonly object PageIndexChangedEvent = new object();
                private static readonly object PageIndexChangingEvent = new object();
@@ -102,10 +102,11 @@ namespace System.Web.UI.WebControls
                // Control state
                int pageIndex;
                FormViewMode currentMode = FormViewMode.ReadOnly; 
-               int pageCount = -1;
+               int pageCount = 0;
                
                public FormView ()
                {
+                       key = new DataKey (new OrderedDictionary ());
                }
                
                public event EventHandler PageIndexChanged {
@@ -267,7 +268,7 @@ namespace System.Web.UI.WebControls
                
                [WebCategoryAttribute ("Paging")]
                [DefaultValueAttribute (false)]
-               public bool AllowPaging {
+               public virtual bool AllowPaging {
                        get {
                                object ob = ViewState ["AllowPaging"];
                                if (ob != null) return (bool) ob;
@@ -282,7 +283,7 @@ 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"];
@@ -307,7 +308,7 @@ 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;
@@ -344,6 +345,8 @@ namespace System.Web.UI.WebControls
                                return -1;
                        }
                        set {
+                               if (value < -1)
+                                       throw new ArgumentOutOfRangeException ("< -1");
                                ViewState ["CellPadding"] = value;
                                RequireBinding ();
                        }
@@ -359,46 +362,49 @@ namespace System.Web.UI.WebControls
                                return 0;
                        }
                        set {
-                               ViewState ["CellSpacing"] = value;
+                               if (value < -1)
+                                       throw new ArgumentOutOfRangeException ("< -1");
+                               ViewState["CellSpacing"] = value;
                                RequireBinding ();
                        }
                }
                
-           [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]\r
-           [BrowsableAttribute (false)]\r
+               [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
+               [BrowsableAttribute (false)]
                public FormViewMode CurrentMode {
                        get {
                                return currentMode;
                        }
                }
-       
-           [DefaultValueAttribute (FormViewMode.ReadOnly)]\r
-           [WebCategoryAttribute ("Behavior")]\r
+
+               FormViewMode defaultMode;
+
+               [DefaultValueAttribute (FormViewMode.ReadOnly)]
+               [WebCategoryAttribute ("Behavior")]
                public virtual FormViewMode DefaultMode {
                        get {
-                               object o = ViewState ["DefaultMode"];
-                               if (o != null) return (FormViewMode) o;
-                               return FormViewMode.ReadOnly;
+                               return defaultMode;
                        }
                        set {
-                               ViewState ["DefaultMode"] = value;
+                               defaultMode = value;
                                RequireBinding ();
                        }
                }
-       
+
+               string[] dataKeyNames;
                [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")]
+               [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;
+                               return dataKeyNames;
                        }
                        set {
-                               ViewState ["DataKeyNames"] = value;
+                               dataKeyNames = value;
                                RequireBinding ();
                        }
                }
@@ -415,18 +421,18 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof(FormView), BindingDirection.TwoWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-           [Browsable (false)]
-               public ITemplate EditItemTemplate {
+               [Browsable (false)]
+               public virtual ITemplate EditItemTemplate {
                        get { return editItemTemplate; }
                        set { editItemTemplate = value; RequireBinding (); }
                }
 
-           [WebCategoryAttribute ("Styles")]
+               [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 ();
@@ -437,12 +443,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 ();
@@ -456,8 +462,8 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof(FormView), BindingDirection.OneWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-           [Browsable (false)]
-               public ITemplate EmptyDataTemplate {
+               [Browsable (false)]
+               public virtual ITemplate EmptyDataTemplate {
                        get { return emptyDataTemplate; }
                        set { emptyDataTemplate = value; RequireBinding (); }
                }
@@ -489,16 +495,16 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof(FormView), BindingDirection.OneWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-           [Browsable (false)]
-               public ITemplate FooterTemplate {
+               [Browsable (false)]
+               public virtual ITemplate FooterTemplate {
                        get { return footerTemplate; }
                        set { footerTemplate = value; RequireBinding (); }
                }
 
-           [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;
@@ -510,12 +516,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 ();
@@ -530,12 +536,10 @@ namespace System.Web.UI.WebControls
                [DefaultValueAttribute (GridLines.None)]
                public virtual GridLines GridLines {
                        get {
-                               object ob = ViewState ["GridLines"];
-                               if (ob != null) return (GridLines) ob;
-                               return GridLines.None;
+                               return ((TableStyle) ControlStyle).GridLines;
                        }
                        set {
-                               ViewState ["GridLines"] = value;
+                               ((TableStyle) ControlStyle).GridLines = value;
                        }
                }
 
@@ -548,12 +552,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 ();
@@ -567,16 +571,16 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof(FormView), BindingDirection.OneWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-           [Browsable (false)]
-               public ITemplate HeaderTemplate {
+               [Browsable (false)]
+               public virtual ITemplate HeaderTemplate {
                        get { return headerTemplate; }
                        set { headerTemplate = value; RequireBinding (); }
                }
 
-           [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;
@@ -588,6 +592,7 @@ namespace System.Web.UI.WebControls
                        }
                }
                
+               [Category ("Layout")]
                [DefaultValueAttribute (HorizontalAlign.NotSet)]
                public virtual HorizontalAlign HorizontalAlign {
                        get {
@@ -604,18 +609,18 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof(FormView), BindingDirection.TwoWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-           [Browsable (false)]
-               public ITemplate InsertItemTemplate {
+               [Browsable (false)]
+               public virtual ITemplate InsertItemTemplate {
                        get { return insertItemTemplate; }
                        set { insertItemTemplate = value; RequireBinding (); }
                }
 
-           [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 ();
@@ -629,30 +634,32 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof(FormView), BindingDirection.TwoWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-           [Browsable (false)]
-               public ITemplate ItemTemplate {
+               [Browsable (false)]
+               public virtual ITemplate ItemTemplate {
                        get { return itemTemplate; }
                        set { itemTemplate = value; RequireBinding (); }
                }
                
                [BrowsableAttribute (false)]
                [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
-               public int PageCount {
+               public virtual int PageCount {
                        get {
-                               if (pageCount != -1) return pageCount;
+                               if (pageCount != 0) return pageCount;
                                EnsureDataBound ();
                                return pageCount;
                        }
                }
 
                [WebCategoryAttribute ("Paging")]
-           [BindableAttribute (true, BindingDirection.OneWay)]\r
+               [BindableAttribute (true, BindingDirection.OneWay)]
                [DefaultValueAttribute (0)]
-               public int PageIndex {
+               public virtual int PageIndex {
                        get {
                                return pageIndex;
                        }
                        set {
+                               if (pageIndex == value)
+                                       return;
                                pageIndex = value;
                                RequireBinding ();
                        }
@@ -662,7 +669,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);
@@ -673,11 +680,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 ();
@@ -690,29 +697,30 @@ namespace System.Web.UI.WebControls
                
                
                [DefaultValue (null)]
-               [TemplateContainer (typeof(FormView), BindingDirection.OneWay)]
+               /* DataControlPagerCell isnt specified in the docs */
+               //[TemplateContainer (typeof(DataControlPagerCell), BindingDirection.OneWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-           [Browsable (false)]
-               public ITemplate PagerTemplate {
+               [Browsable (false)]
+               public virtual ITemplate PagerTemplate {
                        get { return pagerTemplate; }
                        set { pagerTemplate = value; RequireBinding (); }
                }
                
-               [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]\r
-               [BrowsableAttribute (false)]\r
-               public FormViewRow Row {
+               [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
+               [BrowsableAttribute (false)]
+               public virtual FormViewRow Row {
                        get {
                                EnsureDataBound ();
                                return itemRow;
                        }
                }
-           \r
-           [WebCategoryAttribute ("Styles")]
+               
+               [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 ();
@@ -723,9 +731,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; }
                }
                
@@ -740,7 +748,7 @@ namespace System.Web.UI.WebControls
        
                [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
                [BrowsableAttribute (false)]
-               public object DataItem {
+               public virtual object DataItem {
                        get {
                                EnsureDataBound ();
                                return dataItem;
@@ -755,9 +763,13 @@ namespace System.Web.UI.WebControls
        
                [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
                [BrowsableAttribute (false)]
-               public int DataItemIndex {
+               public virtual int DataItemIndex {
                        get { return PageIndex; }
-               }               
+               }
+
+               int IDataItemContainer.DataItemIndex {
+                       get { return DataItemIndex; }
+               }
        
                int IDataItemContainer.DisplayIndex {
                        get { return PageIndex; }
@@ -765,7 +777,7 @@ namespace System.Web.UI.WebControls
        
                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 ()
@@ -783,8 +795,8 @@ namespace System.Web.UI.WebControls
                void RequireBinding ()
                {
                        if (Initialized) {
-                               RequiresDataBinding = true;
                                pageCount = -1;
+                               RequiresDataBinding = true;
                        }
                }
                
@@ -799,47 +811,39 @@ namespace System.Web.UI.WebControls
                        table.BackImageUrl = BackImageUrl;
                        return table;
                }
+
+               [MonoTODO]
+               protected override void EnsureDataBound ()
+               {
+                       base.EnsureDataBound ();
+               }
        
+               protected override Style CreateControlStyle ()
+               {
+                       TableStyle style = new TableStyle (ViewState);
+                       style.CellSpacing = 0;
+                       return style;
+               }
+               
                protected override int CreateChildControls (IEnumerable data, bool dataBinding)
                {
-                       PagedDataSource dataSource;
+                       PagedDataSource dataSource = new PagedDataSource ();
+                       dataSource.DataSource = data;
+                       dataSource.AllowPaging = AllowPaging;
+                       dataSource.PageSize = 1;
+                       dataSource.CurrentPageIndex = PageIndex;
 
                        if (dataBinding) {
                                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) {
+                                       dataSource.AllowServerPaging = true;
+                                       if (view.CanRetrieveTotalRowCount)
+                                               dataSource.VirtualCount = SelectArguments.TotalRowCount;
                                }
                        }
 
-                       bool showPager = AllowPaging && (PageCount > 1);
-                       dataSourceCount = dataSource.Count;
+                       pageCount = dataSource.DataSourceCount;
+                       bool showPager = AllowPaging && (pageCount > 1);
                        
                        Controls.Clear ();
                        table = CreateTable ();
@@ -851,10 +855,16 @@ namespace System.Web.UI.WebControls
                        // Gets the current data item
                        
                        IEnumerator e = dataSource.GetEnumerator (); 
-                       if (e.MoveNext ())
-                               dataItem = e.Current;
+                       dataItem = null;
+
+                       if (AllowPaging) {
+                               if (e.MoveNext ())
+                                       dataItem = e.Current;
+                       }
                        else
-                               dataItem = null;
+                       for (int page = 0; e.MoveNext (); page++ )
+                               if (page == PageIndex)
+                                       dataItem = e.Current;
                        
                        // Main table creation
                        
@@ -870,7 +880,7 @@ namespace System.Web.UI.WebControls
                                table.Rows.Add (topPagerRow);
                        }
 
-                       if (dataSourceCount > 0) {
+                       if (pageCount > 0) {
                                DataControlRowState rstate = GetRowState ();
                                itemRow = CreateRow (0, DataControlRowType.DataRow, rstate);
                                InitializeRow (itemRow);
@@ -882,13 +892,23 @@ namespace System.Web.UI.WebControls
                                        key = new DataKey (new OrderedDictionary (), DataKeyNames);
                                }
                        } else {
-                               itemRow = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
+                               switch (CurrentMode) {
+                               case FormViewMode.Edit:
+                                       itemRow = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Edit);
+                                       break;
+                               case FormViewMode.Insert:
+                                       itemRow = CreateRow (-1, DataControlRowType.DataRow, DataControlRowState.Insert);
+                                       break;
+                               default:
+                                       itemRow = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
+                                       break;
+                               }
                                table.Rows.Add (itemRow);
                                InitializeRow (itemRow);
                        }
                                
                        if (showPager && PagerSettings.Position == PagerPosition.Bottom || PagerSettings.Position == PagerPosition.TopAndBottom) {
-                               bottomPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
+                               bottomPagerRow = CreateRow (0, DataControlRowType.Pager, DataControlRowState.Normal);
                                InitializePager (bottomPagerRow, dataSource);
                                table.Rows.Add (bottomPagerRow);
                        }
@@ -916,11 +936,12 @@ namespace System.Web.UI.WebControls
                protected virtual void InitializePager (FormViewRow row, PagedDataSource dataSource)
                {
                        TableCell cell = new TableCell ();
-                       
+                       cell.ColumnSpan = 2;
+
                        if (pagerTemplate != null)
                                pagerTemplate.InstantiateIn (cell);
                        else
-                               cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount));
+                               cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount, pagerStyle));
                        
                        row.Cells.Add (cell);
                }
@@ -961,6 +982,7 @@ namespace System.Web.UI.WebControls
                                else
                                        cell.Text = HeaderText;
                        }
+                       cell.ColumnSpan = 2;
                        row.Cells.Add (cell);
                }
                
@@ -992,6 +1014,9 @@ namespace System.Web.UI.WebControls
                
                protected virtual void ExtractRowValues (IOrderedDictionary fieldValues, bool includeKeys)
                {
+                       if (Row == null)
+                               return;
+
                        DataControlRowState rowState = Row.RowState;
                        IBindableTemplate bt;
                        
@@ -1019,6 +1044,12 @@ namespace System.Web.UI.WebControls
                
                public sealed override void DataBind ()
                {
+                       if (CurrentMode == FormViewMode.Insert) {
+                               RequiresDataBinding = false;
+                               PerformDataBinding (new object [] { null });
+                               return;
+                       }
+                       
                        DataSourceView view = GetData ();
                        if (AllowPaging && view.CanPage) {
                                SelectArguments.StartRowIndex = PageIndex;
@@ -1030,28 +1061,30 @@ namespace System.Web.UI.WebControls
                        cachedKeyProperties = null;
                        base.DataBind ();
                        
-                       if (dataSourceCount > 0) {
+                       if (pageCount > 0) {
                                if (CurrentMode == FormViewMode.Edit)
                                        oldEditValues = new DataKey (GetRowValues (true));
+                               else
+                                       oldEditValues = new DataKey (new OrderedDictionary ());
                                key = new DataKey (CreateRowDataKey (dataItem), DataKeyNames);
                        }
                }
                
-               protected override void PerformDataBinding (IEnumerable data)
+               protected internal override void PerformDataBinding (IEnumerable data)
                {
                        base.PerformDataBinding (data);
                }
-               
-               protected override void OnInit (EventArgs e)
+
+               [MonoTODO]
+               protected internal virtual void PrepareControlHierarchy ()
                {
-                       Page.RegisterRequiresControlState (this);
-                       base.OnInit (e);
+                       throw new NotImplementedException ();
                }
                
-               protected override void OnDataSourceViewChanged (object sender, EventArgs e)
+               protected internal override void OnInit (EventArgs e)
                {
-                       base.OnDataSourceViewChanged (sender, e);
-                       RequireBinding ();
+                       Page.RegisterRequiresControlState (this);
+                       base.OnInit (e);
                }
                
                protected override bool OnBubbleEvent (object source, EventArgs e)
@@ -1064,7 +1097,11 @@ namespace System.Web.UI.WebControls
                        return base.OnBubbleEvent (source, e);
                }
                
-               // This is prolly obsolete
+                void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
+               {
+                       RaisePostBackEvent (eventArgument);
+               }
+
                protected virtual void RaisePostBackEvent (string eventArgument)
                {
                        int i = eventArgument.IndexOf ('$');
@@ -1078,69 +1115,71 @@ namespace System.Web.UI.WebControls
                {
                        switch (eventName)
                        {
-                               case DataControlCommands.PageCommandName:
-                                       int newIndex = -1;
-                                       switch (param) {
-                                               case DataControlCommands.FirstPageCommandArgument:
-                                                       newIndex = 0;
-                                                       break;
-                                               case DataControlCommands.LastPageCommandArgument:
-                                                       newIndex = PageCount - 1;
-                                                       break;
-                                               case DataControlCommands.NextPageCommandArgument:
-                                                       if (PageIndex < PageCount - 1) newIndex = PageIndex + 1;
-                                                       break;
-                                               case DataControlCommands.PreviousPageCommandArgument:
-                                                       if (PageIndex > 0) newIndex = PageIndex - 1;
-                                                       break;
-                                               default:
-                                                       newIndex = int.Parse (param) - 1;
-                                                       break;
-                                       }
-                                       ShowPage (newIndex);
-                                       break;
-                                       
+                       case DataControlCommands.PageCommandName:
+                               int newIndex = -1;
+                               switch (param) {
                                case DataControlCommands.FirstPageCommandArgument:
-                                       ShowPage (0);
+                                       newIndex = 0;
                                        break;
-
                                case DataControlCommands.LastPageCommandArgument:
-                                       ShowPage (PageCount - 1);
+                                       newIndex = PageCount - 1;
                                        break;
-                                       
                                case DataControlCommands.NextPageCommandArgument:
-                                       if (PageIndex < PageCount - 1)
-                                               ShowPage (PageIndex + 1);
+                                       newIndex = PageIndex + 1;
                                        break;
-
                                case DataControlCommands.PreviousPageCommandArgument:
-                                       if (PageIndex > 0)
-                                               ShowPage (PageIndex - 1);
+                                       newIndex = PageIndex - 1;
                                        break;
-                                       
-                               case DataControlCommands.EditCommandName:
-                                       ChangeMode (FormViewMode.Edit);
+                               default:
+                                       int paramIndex = 0;
+                                       int.TryParse (param, out paramIndex);
+                                       newIndex = paramIndex - 1;
                                        break;
+                               }
+                               ShowPage (newIndex);
+                               break;
                                        
-                               case DataControlCommands.NewCommandName:
-                                       ChangeMode (FormViewMode.Insert);
-                                       break;
+                       case DataControlCommands.FirstPageCommandArgument:
+                               ShowPage (0);
+                               break;
+
+                       case DataControlCommands.LastPageCommandArgument:
+                               ShowPage (PageCount - 1);
+                               break;
                                        
-                               case DataControlCommands.UpdateCommandName:
-                                       UpdateItem (param, true);
-                                       break;
+                       case DataControlCommands.NextPageCommandArgument:
+                               if (PageIndex < PageCount - 1)
+                                       ShowPage (PageIndex + 1);
+                               break;
+
+                       case DataControlCommands.PreviousPageCommandArgument:
+                               if (PageIndex > 0)
+                                       ShowPage (PageIndex - 1);
+                               break;
                                        
-                               case DataControlCommands.CancelCommandName:
-                                       CancelEdit ();
-                                       break;
+                       case DataControlCommands.EditCommandName:
+                               ChangeMode (FormViewMode.Edit);
+                               break;
                                        
-                               case DataControlCommands.DeleteCommandName:
-                                       DeleteItem ();
-                                       break;
+                       case DataControlCommands.NewCommandName:
+                               ChangeMode (FormViewMode.Insert);
+                               break;
                                        
-                               case DataControlCommands.InsertCommandName:
-                                       InsertItem (true);
-                                       break;
+                       case DataControlCommands.UpdateCommandName:
+                               UpdateItem (param, true);
+                               break;
+                                       
+                       case DataControlCommands.CancelCommandName:
+                               CancelEdit ();
+                               break;
+                                       
+                       case DataControlCommands.DeleteCommandName:
+                               DeleteItem ();
+                               break;
+                                       
+                       case DataControlCommands.InsertCommandName:
+                               InsertItem (true);
+                               break;
                        }
                }
                
@@ -1149,8 +1188,11 @@ namespace System.Web.UI.WebControls
                        FormViewPageEventArgs args = new FormViewPageEventArgs (newIndex);
                        OnPageIndexChanging (args);
                        if (!args.Cancel) {
-                               EndRowEdit ();
-                               PageIndex = args.NewPageIndex;
+                               newIndex = args.NewPageIndex;
+                               if (newIndex < 0 || newIndex >= PageCount)
+                                       return;
+                               EndRowEdit (false);
+                               PageIndex = newIndex;
                                OnPageIndexChanged (EventArgs.Empty);
                        }
                }
@@ -1195,13 +1237,16 @@ namespace System.Web.UI.WebControls
                        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
+                               if (view == null)
+                                       throw new HttpException ("The DataSourceView associated to data bound control was null");
+                               if (view.CanUpdate)
+                                       view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback));
+                       }
+                       else
                                EndRowEdit ();
                }
 
-        bool UpdateCallback (int recordsAffected, Exception exception)
+               bool UpdateCallback (int recordsAffected, Exception exception)
                {
                        FormViewUpdatedEventArgs dargs = new FormViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
                        OnItemUpdated (dargs);
@@ -1229,13 +1274,16 @@ namespace System.Web.UI.WebControls
                        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
+                               if (view == null)
+                                       throw new HttpException ("The DataSourceView associated to data bound control was null");
+                               if (view.CanInsert)
+                                       view.Insert (currentEditNewValues, new DataSourceViewOperationCallback (InsertCallback));
+                       }
+                       else
                                EndRowEdit ();
                }
                
-        bool InsertCallback (int recordsAffected, Exception exception)
+               bool InsertCallback (int recordsAffected, Exception exception)
                {
                        FormViewInsertedEventArgs dargs = new FormViewInsertedEventArgs (recordsAffected, exception, currentEditNewValues);
                        OnItemInserted (dargs);
@@ -1246,7 +1294,7 @@ namespace System.Web.UI.WebControls
                        return dargs.ExceptionHandled;
                }
 
-               public void DeleteItem ()
+               public virtual void DeleteItem ()
                {
                        currentEditRowKeys = DataKey.Values;
                        currentEditNewValues = GetRowValues (true);
@@ -1261,7 +1309,7 @@ namespace System.Web.UI.WebControls
                                RequireBinding ();
                                        
                                DataSourceView view = GetData ();
-                               if (view != null)
+                               if (view != null && view.CanDelete)
                                        view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
                                else {
                                        FormViewDeletedEventArgs dargs = new FormViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
@@ -1270,7 +1318,7 @@ namespace System.Web.UI.WebControls
                        }
                }
 
-        bool DeleteCallback (int recordsAffected, Exception exception)
+               bool DeleteCallback (int recordsAffected, Exception exception)
                {
                        FormViewDeletedEventArgs dargs = new FormViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues);
                        OnItemDeleted (dargs);
@@ -1279,7 +1327,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;
@@ -1295,13 +1349,15 @@ namespace System.Web.UI.WebControls
                        pageIndex = (int) state[1];
                        pageCount = (int) state[2];
                        currentMode = (FormViewMode) state[3];
+                       defaultMode = (FormViewMode) state[4];
+                       dataKeyNames = (string[]) state[5];
                }
                
                protected internal override object SaveControlState ()
                {
                        object bstate = base.SaveControlState ();
                        return new object[] {
-                               bstate, pageIndex, pageCount, currentMode
+                               bstate, pageIndex, pageCount, currentMode, defaultMode, dataKeyNames
                        };
                }
                
@@ -1366,48 +1422,51 @@ namespace System.Web.UI.WebControls
                        if (states[12] != null && oldEditValues != null) ((IStateManager)oldEditValues).LoadViewState (states[12]);
                }
                
-               protected override void Render (HtmlTextWriter writer)
+               protected internal override void Render (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;
+                       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");
+                       if (!string.IsNullOrEmpty (ControlStyle.CssClass))
+                               writer.AddAttribute (HtmlTextWriterAttribute.Class, ControlStyle.CssClass);
+
+                       table.ControlStyle.MergeWith (ControlStyle);
                        table.RenderBeginTag (writer);
                        
                        foreach (FormViewRow 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;
+                               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 ((row.RowState & DataControlRowState.Edit) != 0 && editRowStyle != null)
@@ -1424,6 +1483,13 @@ namespace System.Web.UI.WebControls
                        }
                        table.RenderEndTag (writer);
                }
+
+               PostBackOptions IPostBackContainer.GetPostBackOptions (IButtonControl control)
+               {
+                       Control ctrl = control as Control;
+                       return new PostBackOptions(ctrl);
+               }
+
        }
 }