New tests.
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / FormView.cs
index ea63e1d7ea26f52820143b2e5ee28bf50c3d2abb..099ceb54126870937b3078e7a62e0b4d90078923 100644 (file)
@@ -71,6 +71,7 @@ namespace System.Web.UI.WebControls
                
                PropertyDescriptor[] cachedKeyProperties;
                readonly string[] emptyKeys = new string[0];
+               readonly string unhandledEventExceptionMessage = "The FormView '{0}' fired event {1} which wasn't handled.";
                
                // View state
                PagerSettings pagerSettings;
@@ -83,31 +84,28 @@ namespace System.Web.UI.WebControls
                TableItemStyle pagerStyle;
                TableItemStyle rowStyle;
                
+               IOrderedDictionary _keyTable;
                DataKey key;
                DataKey oldEditValues;
                
-               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;
                FormViewMode currentMode = FormViewMode.ReadOnly; 
-               int pageCount = 0;
-               
-               public FormView ()
-               {
-                       key = new DataKey (new OrderedDictionary ());
-               }
+               bool hasCurrentMode;
+               int pageCount;
                
                public event EventHandler PageIndexChanged {
                        add { Events.AddHandler (PageIndexChangedEvent, value); }
@@ -181,8 +179,13 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                FormViewPageEventHandler eh = (FormViewPageEventHandler) 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 (FormViewCommandEventArgs e)
@@ -221,16 +224,26 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                FormViewInsertEventHandler eh = (FormViewInsertEventHandler) 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 (FormViewDeleteEventArgs e)
                {
                        if (Events != null) {
                                FormViewDeleteEventHandler eh = (FormViewDeleteEventHandler) 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)
@@ -245,8 +258,13 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                FormViewModeEventHandler eh = (FormViewModeEventHandler) 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 (FormViewUpdatedEventArgs e)
@@ -261,8 +279,13 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                FormViewUpdateEventHandler eh = (FormViewUpdateEventHandler) 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"));
                }
                
                
@@ -286,13 +309,12 @@ namespace System.Web.UI.WebControls
                [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;
                        }
                }
 
@@ -300,7 +322,7 @@ namespace System.Web.UI.WebControls
                [BrowsableAttribute (false)]
                public virtual FormViewRow BottomPagerRow {
                        get {
-                               EnsureDataBound ();
+                               EnsureChildControls ();
                                return bottomPagerRow;
                        }
                }
@@ -340,15 +362,12 @@ namespace System.Web.UI.WebControls
                public virtual int CellPadding
                {
                        get {
-                               object o = ViewState ["CellPadding"];
-                               if (o != null) return (int) o;
+                               if (ControlStyleCreated)
+                                       return ((TableStyle) ControlStyle).CellPadding;
                                return -1;
                        }
                        set {
-                               if (value < -1)
-                                       throw new ArgumentOutOfRangeException ("< -1");
-                               ViewState ["CellPadding"] = value;
-                               RequireBinding ();
+                               ((TableStyle) ControlStyle).CellPadding = value;
                        }
                }
 
@@ -357,15 +376,12 @@ namespace System.Web.UI.WebControls
                public virtual int CellSpacing
                {
                        get {
-                               object o = ViewState ["CellSpacing"];
-                               if (o != null) return (int) o;
+                               if (ControlStyleCreated)
+                                       return ((TableStyle) ControlStyle).CellSpacing;
                                return 0;
                        }
                        set {
-                               if (value < -1)
-                                       throw new ArgumentOutOfRangeException ("< -1");
-                               ViewState["CellSpacing"] = value;
-                               RequireBinding ();
+                               ((TableStyle) ControlStyle).CellSpacing = value;
                        }
                }
                
@@ -373,7 +389,11 @@ namespace System.Web.UI.WebControls
                [BrowsableAttribute (false)]
                public FormViewMode CurrentMode {
                        get {
-                               return currentMode;
+                               return hasCurrentMode ? currentMode : DefaultMode;
+                       }
+                       private set {
+                               hasCurrentMode = true;
+                               currentMode = value;
                        }
                }
 
@@ -409,22 +429,42 @@ namespace System.Web.UI.WebControls
                        }
                }
                
+               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;
                        }
                }
 
+               DataKey OldEditValues {
+                       get {
+                               if (oldEditValues == null) {
+                                       oldEditValues = new DataKey (new OrderedDictionary ());
+                               }
+                               return oldEditValues;
+                       }
+               }
+
                [DefaultValue (null)]
                [TemplateContainer (typeof(FormView), BindingDirection.TwoWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [Browsable (false)]
                public virtual ITemplate EditItemTemplate {
                        get { return editItemTemplate; }
-                       set { editItemTemplate = value; RequireBinding (); }
+                       set { editItemTemplate = value; }
                }
 
                [WebCategoryAttribute ("Styles")]
@@ -465,7 +505,7 @@ namespace System.Web.UI.WebControls
                [Browsable (false)]
                public virtual ITemplate EmptyDataTemplate {
                        get { return emptyDataTemplate; }
-                       set { emptyDataTemplate = value; RequireBinding (); }
+                       set { emptyDataTemplate = value; }
                }
                
                [LocalizableAttribute (true)]
@@ -498,7 +538,7 @@ namespace System.Web.UI.WebControls
                [Browsable (false)]
                public virtual ITemplate FooterTemplate {
                        get { return footerTemplate; }
-                       set { footerTemplate = value; RequireBinding (); }
+                       set { footerTemplate = value; }
                }
 
                [LocalizableAttribute (true)]
@@ -536,7 +576,9 @@ namespace System.Web.UI.WebControls
                [DefaultValueAttribute (GridLines.None)]
                public virtual GridLines GridLines {
                        get {
-                               return ((TableStyle) ControlStyle).GridLines;
+                               if (ControlStyleCreated)
+                                       return ((TableStyle) ControlStyle).GridLines;
+                               return GridLines.None;
                        }
                        set {
                                ((TableStyle) ControlStyle).GridLines = value;
@@ -574,7 +616,7 @@ namespace System.Web.UI.WebControls
                [Browsable (false)]
                public virtual ITemplate HeaderTemplate {
                        get { return headerTemplate; }
-                       set { headerTemplate = value; RequireBinding (); }
+                       set { headerTemplate = value; }
                }
 
                [LocalizableAttribute (true)]
@@ -596,13 +638,12 @@ namespace System.Web.UI.WebControls
                [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 ();
+                               ((TableStyle) ControlStyle).HorizontalAlign = value;
                        }
                }
 
@@ -612,7 +653,7 @@ namespace System.Web.UI.WebControls
                [Browsable (false)]
                public virtual ITemplate InsertItemTemplate {
                        get { return insertItemTemplate; }
-                       set { insertItemTemplate = value; RequireBinding (); }
+                       set { insertItemTemplate = value; }
                }
 
                [WebCategoryAttribute ("Styles")]
@@ -637,17 +678,18 @@ namespace System.Web.UI.WebControls
                [Browsable (false)]
                public virtual ITemplate ItemTemplate {
                        get { return itemTemplate; }
-                       set { itemTemplate = value; RequireBinding (); }
+                       set { itemTemplate = value; }
                }
                
                [BrowsableAttribute (false)]
                [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
                public virtual int PageCount {
                        get {
-                               if (pageCount != 0) return pageCount;
-                               EnsureDataBound ();
                                return pageCount;
                        }
+                       private set {
+                               pageCount = value;
+                       }
                }
 
                [WebCategoryAttribute ("Paging")]
@@ -658,7 +700,9 @@ namespace System.Web.UI.WebControls
                                return pageIndex;
                        }
                        set {
-                               if (pageIndex == value)
+                               if (value < -1)
+                                       throw new ArgumentOutOfRangeException ("PageIndex must be non-negative");
+                               if (pageIndex == value || value == -1)
                                        return;
                                pageIndex = value;
                                RequireBinding ();
@@ -697,20 +741,19 @@ namespace System.Web.UI.WebControls
                
                
                [DefaultValue (null)]
-               /* DataControlPagerCell isnt specified in the docs */
-               //[TemplateContainer (typeof(DataControlPagerCell), BindingDirection.OneWay)]
+               [TemplateContainerAttribute (typeof (FormView))]
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [Browsable (false)]
                public virtual ITemplate PagerTemplate {
                        get { return pagerTemplate; }
-                       set { pagerTemplate = value; RequireBinding (); }
+                       set { pagerTemplate = value; }
                }
                
                [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
                [BrowsableAttribute (false)]
                public virtual FormViewRow Row {
                        get {
-                               EnsureDataBound ();
+                               EnsureChildControls ();
                                return itemRow;
                        }
                }
@@ -741,7 +784,7 @@ namespace System.Web.UI.WebControls
                [BrowsableAttribute (false)]
                public virtual FormViewRow TopPagerRow {
                        get {
-                               EnsureDataBound ();
+                               EnsureChildControls ();
                                return topPagerRow;
                        }
                }
@@ -750,7 +793,6 @@ namespace System.Web.UI.WebControls
                [BrowsableAttribute (false)]
                public virtual object DataItem {
                        get {
-                               EnsureDataBound ();
                                return dataItem;
                        }
                }
@@ -782,40 +824,54 @@ namespace System.Web.UI.WebControls
                
                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 FormViewRow CreateRow (int rowIndex, DataControlRowType rowType, DataControlRowState rowState)
                {
-                       FormViewRow row = new FormViewRow (rowIndex, rowType, rowState);
-                       OnItemCreated (EventArgs.Empty);
-                       return row;
+                       if (rowType == DataControlRowType.Pager)
+                               return new FormViewPagerRow (rowIndex, rowType, rowState);
+                       else
+                               return new FormViewRow (rowIndex, rowType, rowState);
                }
                
                void RequireBinding ()
                {
                        if (Initialized) {
-                               pageCount = -1;
                                RequiresDataBinding = true;
                        }
                }
                
                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);
                }
 
-               [MonoTODO]
                protected override void EnsureDataBound ()
                {
-                       base.EnsureDataBound ();
+                       if (CurrentMode == FormViewMode.Insert) {
+                               if (RequiresDataBinding) {
+                                       OnDataBinding (EventArgs.Empty);
+                                       RequiresDataBinding = false;
+                                       InternalPerformDataBinding (null);
+                                       MarkAsDataBound ();
+                                       OnDataBound (EventArgs.Empty);
+                               }
+                       }
+                       else
+                               base.EnsureDataBound ();
                }
        
                protected override Style CreateControlStyle ()
@@ -828,69 +884,82 @@ namespace System.Web.UI.WebControls
                protected override int CreateChildControls (IEnumerable data, bool dataBinding)
                {
                        PagedDataSource dataSource = new PagedDataSource ();
-                       dataSource.DataSource = data;
+                       dataSource.DataSource = CurrentMode != FormViewMode.Insert ? data : null;
                        dataSource.AllowPaging = AllowPaging;
                        dataSource.PageSize = 1;
                        dataSource.CurrentPageIndex = PageIndex;
 
-                       if (dataBinding) {
+                       if (dataBinding && CurrentMode != FormViewMode.Insert) {
                                DataSourceView view = GetData ();
                                if (view != null && view.CanPage) {
                                        dataSource.AllowServerPaging = true;
-                                       if (view.CanRetrieveTotalRowCount)
+                                       if (SelectArguments.RetrieveTotalRowCount)
                                                dataSource.VirtualCount = SelectArguments.TotalRowCount;
                                }
                        }
 
-                       pageCount = dataSource.DataSourceCount;
-                       bool showPager = AllowPaging && (pageCount > 1);
+                       PagerSettings pagerSettings = PagerSettings;
+                       bool showPager = AllowPaging && pagerSettings.Visible && (dataSource.PageCount > 1);
                        
                        Controls.Clear ();
                        table = CreateTable ();
                        Controls.Add (table);
-                               
-                       if (!Page.IsPostBack)
-                               currentMode = DefaultMode;
+                       headerRow = null;
+                       footerRow = null;
+                       topPagerRow = null;
+                       bottomPagerRow = null;
 
                        // Gets the current data item
-                       
-                       IEnumerator e = dataSource.GetEnumerator (); 
-                       dataItem = null;
 
                        if (AllowPaging) {
-                               if (e.MoveNext ())
-                                       dataItem = e.Current;
+                               PageCount = dataSource.DataSourceCount;
+                               if (PageIndex >= PageCount && PageCount > 0) {
+                                       pageIndex = dataSource.CurrentPageIndex = PageCount - 1;
+                               }
+                               if (dataSource.DataSource != null) {
+                                       IEnumerator e = dataSource.GetEnumerator ();
+                                       if (e.MoveNext ())
+                                               dataItem = e.Current;
+                               }
                        }
-                       else
-                       for (int page = 0; e.MoveNext (); page++ )
-                               if (page == PageIndex)
-                                       dataItem = e.Current;
-                       
+                       else {
+                               int page = 0;
+                               object lastItem = null;
+                               if (dataSource.DataSource != null) {
+                                       IEnumerator e = dataSource.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) {
+                       bool emptyRow = PageCount == 0 && CurrentMode != FormViewMode.Insert;
+
+                       if (!emptyRow) {
                                headerRow = CreateRow (-1, DataControlRowType.Header, DataControlRowState.Normal);
                                InitializeRow (headerRow);
                                table.Rows.Add (headerRow);
                        }
-                       
-                       if (showPager && PagerSettings.Position == PagerPosition.Top || PagerSettings.Position == PagerPosition.TopAndBottom) {
+
+                       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 (pageCount > 0) {
+                       if (PageCount > 0) {
                                DataControlRowState rstate = GetRowState ();
                                itemRow = CreateRow (0, DataControlRowType.DataRow, rstate);
                                InitializeRow (itemRow);
                                table.Rows.Add (itemRow);
-                               
-                               if (!dataBinding) {
-                                       if (CurrentMode == FormViewMode.Edit)
-                                               oldEditValues = new DataKey (new OrderedDictionary ());
-                                       key = new DataKey (new OrderedDictionary (), DataKeyNames);
-                               }
                        } else {
                                switch (CurrentMode) {
                                case FormViewMode.Edit:
@@ -903,26 +972,28 @@ namespace System.Web.UI.WebControls
                                        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 (0, DataControlRowType.Pager, DataControlRowState.Normal);
-                               InitializePager (bottomPagerRow, dataSource);
-                               table.Rows.Add (bottomPagerRow);
+                               table.Rows.Add (itemRow);
                        }
 
-                       if (FooterText.Length != 0 || footerTemplate != null) {
+                       if (!emptyRow) {
                                footerRow = CreateRow (-1, DataControlRowType.Footer, DataControlRowState.Normal);
                                InitializeRow (footerRow);
                                table.Rows.Add (footerRow);
                        }
                        
+                       if (showPager && pagerSettings.Position == PagerPosition.Bottom || pagerSettings.Position == PagerPosition.TopAndBottom) {
+                               bottomPagerRow = CreateRow (0, DataControlRowType.Pager, DataControlRowState.Normal);
+                               InitializePager (bottomPagerRow, dataSource);
+                               table.Rows.Add (bottomPagerRow);
+                       }
+
+                       OnItemCreated (EventArgs.Empty);
+                       
                        if (dataBinding)
                                DataBind (false);
-                       
-                       return dataSource.DataSourceCount;
+
+                       return PageCount;
                }
                
                DataControlRowState GetRowState ()
@@ -941,7 +1012,7 @@ namespace System.Web.UI.WebControls
                        if (pagerTemplate != null)
                                pagerTemplate.InstantiateIn (cell);
                        else
-                               cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount, pagerStyle));
+                               cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount));
                        
                        row.Cells.Add (cell);
                }
@@ -955,54 +1026,66 @@ namespace System.Web.UI.WebControls
                                if ((row.RowState & DataControlRowState.Edit) != 0) {
                                        if (editItemTemplate != null)
                                                editItemTemplate.InstantiateIn (cell);
+                                       else
+                                               row.Visible = false;
                                } else if ((row.RowState & DataControlRowState.Insert) != 0) {
                                        if (insertItemTemplate != null)
                                                insertItemTemplate.InstantiateIn (cell);
-                               } else if (itemTemplate != null)
+                                       else
+                                               row.Visible = false;
+                               }
+                               else if (itemTemplate != null)
                                        itemTemplate.InstantiateIn (cell);
+                               else
+                                       row.Visible = false;
                        }
                        else if (row.RowType == DataControlRowType.EmptyDataRow)
                        {
                                if (emptyDataTemplate != null)
                                        emptyDataTemplate.InstantiateIn (cell);
-                               else
+                               else if (!String.IsNullOrEmpty (EmptyDataText))
                                        cell.Text = EmptyDataText;
+                               else
+                                       row.Visible = false;
                        }
                        else if (row.RowType == DataControlRowType.Footer)
                        {
                                if (footerTemplate != null)
                                        footerTemplate.InstantiateIn (cell);
-                               else
+                               else if (!String.IsNullOrEmpty (FooterText))
                                        cell.Text = FooterText;
+                               else
+                                       row.Visible = false;
                        }
                        else if (row.RowType == DataControlRowType.Header)
                        {
                                if (headerTemplate != null)
                                        headerTemplate.InstantiateIn (cell);
-                               else
+                               else if (!String.IsNullOrEmpty (HeaderText))
                                        cell.Text = HeaderText;
+                               else
+                                       row.Visible = false;
                        }
                        cell.ColumnSpan = 2;
                        row.Cells.Add (cell);
                }
                
-               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 includePrimaryKey)
@@ -1029,6 +1112,7 @@ namespace System.Web.UI.WebControls
                        
                        if (bt != null) {
                                IOrderedDictionary values = bt.ExtractValues (Row.Cells [0]);
+                               if (values != null)
                                foreach (DictionaryEntry e in values) {
                                        if (includeKeys || Array.IndexOf (DataKeyNames, e.Key) == -1)
                                                fieldValues [e.Key] = e.Value;
@@ -1044,29 +1128,14 @@ 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;
-                               SelectArguments.MaximumRows = 1;
-                               if (view.CanRetrieveTotalRowCount)
-                                       SelectArguments.RetrieveTotalRowCount = true;
-                       }
-
                        cachedKeyProperties = null;
                        base.DataBind ();
                        
                        if (pageCount > 0) {
                                if (CurrentMode == FormViewMode.Edit)
                                        oldEditValues = new DataKey (GetRowValues (true));
-                               else
-                                       oldEditValues = new DataKey (new OrderedDictionary ());
-                               key = new DataKey (CreateRowDataKey (dataItem), DataKeyNames);
+                               FillRowDataKey (dataItem);
+                               key = new DataKey (KeyTable);
                        }
                }
                
@@ -1075,10 +1144,44 @@ namespace System.Web.UI.WebControls
                        base.PerformDataBinding (data);
                }
 
-               [MonoTODO]
                protected internal virtual void PrepareControlHierarchy ()
                {
-                       throw new NotImplementedException ();
+                       if (table == null)
+                               return;
+
+                       table.Caption = Caption;
+                       table.CaptionAlign = CaptionAlign;
+
+                       foreach (FormViewRow 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.Edit | DataControlRowState.Insert)) != 0 && editRowStyle != null && !editRowStyle.IsEmpty)
+                                               row.ControlStyle.CopyFrom (editRowStyle);
+                                       if ((row.RowState & DataControlRowState.Insert) != 0 && insertRowStyle != null && !insertRowStyle.IsEmpty)
+                                               row.ControlStyle.CopyFrom (insertRowStyle);
+                                       break;
+                               default:
+                                       break;
+                               }
+                       }
                }
                
                protected internal override void OnInit (EventArgs e)
@@ -1091,13 +1194,25 @@ namespace System.Web.UI.WebControls
                {
                        FormViewCommandEventArgs args = e as FormViewCommandEventArgs;
                        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 (FormViewCommandEventArgs args, bool causesValidation)
+               {
+                       OnItemCommand (args);
+                       ProcessEvent (args.CommandName, args.CommandArgument as string, causesValidation);
+               }
                
-                void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
+               void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
                {
                        RaisePostBackEvent (eventArgument);
                }
@@ -1105,13 +1220,15 @@ namespace System.Web.UI.WebControls
                protected virtual void RaisePostBackEvent (string 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 FormViewCommandEventArgs (this, arg), false);
                }
-               
-               void ProcessEvent (string eventName, string param)
+
+               void ProcessEvent (string eventName, string param, bool causesValidation)
                {
                        switch (eventName)
                        {
@@ -1158,15 +1275,15 @@ namespace System.Web.UI.WebControls
                                break;
                                        
                        case DataControlCommands.EditCommandName:
-                               ChangeMode (FormViewMode.Edit);
+                               ProcessChangeMode (FormViewMode.Edit, false);
                                break;
                                        
                        case DataControlCommands.NewCommandName:
-                               ChangeMode (FormViewMode.Insert);
+                               ProcessChangeMode (FormViewMode.Insert, false);
                                break;
                                        
                        case DataControlCommands.UpdateCommandName:
-                               UpdateItem (param, true);
+                               UpdateItem (param, causesValidation);
                                break;
                                        
                        case DataControlCommands.CancelCommandName:
@@ -1178,43 +1295,51 @@ namespace System.Web.UI.WebControls
                                break;
                                        
                        case DataControlCommands.InsertCommandName:
-                               InsertItem (true);
+                               InsertItem (causesValidation);
                                break;
                        }
                }
                
-               void ShowPage (int newIndex)
+               void ShowPage (int index)
                {
-                       FormViewPageEventArgs args = new FormViewPageEventArgs (newIndex);
+                       FormViewPageEventArgs args = new FormViewPageEventArgs (index);
                        OnPageIndexChanging (args);
-                       if (!args.Cancel) {
-                               newIndex = args.NewPageIndex;
-                               if (newIndex < 0 || newIndex >= PageCount)
-                                       return;
-                               EndRowEdit (false);
-                               PageIndex = newIndex;
-                               OnPageIndexChanged (EventArgs.Empty);
-                       }
+
+                       if (args.Cancel || !IsBoundUsingDataSourceID)
+                               return;
+
+                       int newIndex = args.NewPageIndex;
+                       if (newIndex < 0 || newIndex >= PageCount)
+                               return;
+                       EndRowEdit (false, false);
+                       PageIndex = newIndex;
+                       OnPageIndexChanged (EventArgs.Empty);
                }
                
                public void ChangeMode (FormViewMode newMode)
                {
-                       FormViewModeEventArgs args = new FormViewModeEventArgs (newMode, false);
+                       if (CurrentMode == newMode)
+                               return;
+                       CurrentMode = newMode;
+                       RequireBinding ();
+               }
+
+               void ProcessChangeMode (FormViewMode newMode, bool cancelingEdit)
+               {
+                       FormViewModeEventArgs args = new FormViewModeEventArgs (newMode, cancelingEdit);
                        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 ()
                {
-                       FormViewModeEventArgs args = new FormViewModeEventArgs (FormViewMode.ReadOnly, true);
-                       OnModeChanging (args);
-                       if (!args.Cancel) {
-                               EndRowEdit ();
-                       }
+                       EndRowEdit (true, true);
                }
 
                public virtual void UpdateItem (bool causesValidation)
@@ -1224,26 +1349,25 @@ namespace System.Web.UI.WebControls
                
                void UpdateItem (string param, bool causesValidation)
                {
-                       if (causesValidation)
-                               Page.Validate ();
-                       
-                       if (currentMode != FormViewMode.Edit) throw new NotSupportedException ();
+                       if (causesValidation && Page != null && !Page.IsValid)
+                               return;
                        
-                       currentEditOldValues = oldEditValues.Values;
+                       if (currentMode != FormViewMode.Edit) throw new HttpException ("Must be in Edit mode");
+
+                       currentEditOldValues = OldEditValues.Values;
                        currentEditRowKeys = DataKey.Values;
                        currentEditNewValues = GetRowValues (false);
                        
                        FormViewUpdateEventArgs args = new FormViewUpdateEventArgs (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");
-                               if (view.CanUpdate)
-                                       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)
@@ -1252,7 +1376,7 @@ namespace System.Web.UI.WebControls
                        OnItemUpdated (dargs);
 
                        if (!dargs.KeepInEditMode)                              
-                               EndRowEdit ();
+                               EndRowEdit (true, false);
 
                        return dargs.ExceptionHandled;
                }
@@ -1264,23 +1388,22 @@ namespace System.Web.UI.WebControls
                
                void InsertItem (string param, bool causesValidation)
                {
-                       if (causesValidation)
-                               Page.Validate ();
+                       if (causesValidation && Page != null && !Page.IsValid)
+                               return;
                        
-                       if (currentMode != FormViewMode.Insert) throw new NotSupportedException ();
+                       if (currentMode != FormViewMode.Insert) throw new HttpException ("Must be in Insert mode");
                        
                        currentEditNewValues = GetRowValues (true);
                        FormViewInsertEventArgs args = new FormViewInsertEventArgs (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");
-                               if (view.CanInsert)
-                                       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)
@@ -1289,7 +1412,7 @@ namespace System.Web.UI.WebControls
                        OnItemInserted (dargs);
 
                        if (!dargs.KeepInInsertMode)                            
-                               EndRowEdit ();
+                               EndRowEdit (true, false);
 
                        return dargs.ExceptionHandled;
                }
@@ -1302,21 +1425,22 @@ namespace System.Web.UI.WebControls
                        FormViewDeleteEventArgs args = new FormViewDeleteEventArgs (PageIndex, currentEditRowKeys, currentEditNewValues);
                        OnItemDeleting (args);
 
-                       if (!args.Cancel) {
-                               if (PageIndex == PageCount - 1)
-                                       PageIndex --;
-                                       
-                               RequireBinding ();
-                                       
-                               DataSourceView view = GetData ();
-                               if (view != null && view.CanDelete)
-                                       view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
-                               else {
-                                       FormViewDeletedEventArgs dargs = new FormViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
-                                       OnItemDeleted (dargs);
-                               }
+                       if (args.Cancel || !IsBoundUsingDataSourceID)
+                               return;
+
+                       if (PageIndex > 0 && PageIndex == PageCount - 1)
+                               PageIndex--;
+                               
+                       RequireBinding ();
+                               
+                       DataSourceView view = GetData ();
+                       if (view != null)
+                               view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
+                       else {
+                               FormViewDeletedEventArgs dargs = new FormViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
+                               OnItemDeleted (dargs);
                        }
-               }
+               }       
 
                bool DeleteCallback (int recordsAffected, Exception exception)
                {
@@ -1325,15 +1449,10 @@ namespace System.Web.UI.WebControls
                        return dargs.ExceptionHandled;
                }
                
-               void EndRowEdit ()
-               {
-                       EndRowEdit (true);
-               }
-
-               void EndRowEdit (bool switchToDefaultMode) 
+               void EndRowEdit (bool switchToDefaultMode, bool cancelingEdit) 
                {
                        if (switchToDefaultMode)
-                               ChangeMode (DefaultMode);
+                               ProcessChangeMode (DefaultMode, cancelingEdit);
                        oldEditValues = new DataKey (new OrderedDictionary ());
                        currentEditRowKeys = null;
                        currentEditOldValues = null;
@@ -1348,16 +1467,27 @@ namespace System.Web.UI.WebControls
                        base.LoadControlState (state[0]);
                        pageIndex = (int) state[1];
                        pageCount = (int) state[2];
-                       currentMode = (FormViewMode) state[3];
+                       CurrentMode = (FormViewMode) state[3];
                        defaultMode = (FormViewMode) state[4];
                        dataKeyNames = (string[]) 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, defaultMode, dataKeyNames
+                       return new object [] {
+                               bstate, 
+                               pageIndex, 
+                               pageCount, 
+                               CurrentMode, 
+                               defaultMode, 
+                               dataKeyNames,
+                               (key == null ? null : ((IStateManager)key).SaveViewState()),
+                               (oldEditValues == null ? null : ((IStateManager) oldEditValues).SaveViewState ())
                        };
                }
                
@@ -1372,23 +1502,20 @@ namespace System.Web.UI.WebControls
                        if (editRowStyle != null) ((IStateManager)editRowStyle).TrackViewState();
                        if (insertRowStyle != null) ((IStateManager)insertRowStyle).TrackViewState();
                        if (emptyDataRowStyle != null) ((IStateManager)emptyDataRowStyle).TrackViewState();
-                       if (key != null) ((IStateManager)key).TrackViewState();
                }
 
                protected override object SaveViewState()
                {
-                       object[] states = new object [14];
+                       object[] states = new object [10];
                        states[0] = base.SaveViewState();
-                       states[2] = (pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState());
-                       states[4] = (footerStyle == null ? null : ((IStateManager)footerStyle).SaveViewState());
-                       states[5] = (headerStyle == null ? null : ((IStateManager)headerStyle).SaveViewState());
-                       states[6] = (pagerStyle == null ? null : ((IStateManager)pagerStyle).SaveViewState());
-                       states[7] = (rowStyle == null ? null : ((IStateManager)rowStyle).SaveViewState());
-                       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());
+                       states[1] = (pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState());
+                       states[2] = (footerStyle == null ? null : ((IStateManager)footerStyle).SaveViewState());
+                       states[3] = (headerStyle == null ? null : ((IStateManager)headerStyle).SaveViewState());
+                       states[4] = (pagerStyle == null ? null : ((IStateManager)pagerStyle).SaveViewState());
+                       states[5] = (rowStyle == null ? null : ((IStateManager)rowStyle).SaveViewState());
+                       states[6] = (insertRowStyle == null ? null : ((IStateManager)insertRowStyle).SaveViewState());
+                       states[7] = (editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState());
+                       states[8] = (emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).SaveViewState());
                        
                        for (int i = states.Length - 1; i >= 0; i--) {
                                if (states [i] != null)
@@ -1408,86 +1535,40 @@ namespace System.Web.UI.WebControls
                        object [] states = (object []) savedState;
                        
                        base.LoadViewState (states[0]);
-                       EnsureChildControls ();
                        
-                       if (states[2] != null) ((IStateManager)PagerSettings).LoadViewState (states[2]);
-                       if (states[4] != null) ((IStateManager)FooterStyle).LoadViewState (states[4]);
-                       if (states[5] != null) ((IStateManager)HeaderStyle).LoadViewState (states[5]);
-                       if (states[6] != null) ((IStateManager)PagerStyle).LoadViewState (states[6]);
-                       if (states[7] != null) ((IStateManager)RowStyle).LoadViewState (states[7]);
-                       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 && DataKey != null) ((IStateManager)DataKey).LoadViewState (states[11]);
-                       if (states[12] != null && oldEditValues != null) ((IStateManager)oldEditValues).LoadViewState (states[12]);
+                       if (states[1] != null) ((IStateManager)PagerSettings).LoadViewState (states[1]);
+                       if (states[2] != null) ((IStateManager)FooterStyle).LoadViewState (states[2]);
+                       if (states[3] != null) ((IStateManager)HeaderStyle).LoadViewState (states[3]);
+                       if (states[4] != null) ((IStateManager)PagerStyle).LoadViewState (states[4]);
+                       if (states[5] != null) ((IStateManager)RowStyle).LoadViewState (states[5]);
+                       if (states[6] != null) ((IStateManager)InsertRowStyle).LoadViewState (states[6]);
+                       if (states[7] != null) ((IStateManager)EditRowStyle).LoadViewState (states[7]);
+                       if (states[8] != null) ((IStateManager)EmptyDataRowStyle).LoadViewState (states[8]);
                }
                
                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;
-                       }
+                       PrepareControlHierarchy ();
                        
-                       writer.AddAttribute (HtmlTextWriterAttribute.Cellspacing, "0");
-                       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;
-                               }
-
-                               if ((row.RowState & DataControlRowState.Edit) != 0 && editRowStyle != null)
-                                       editRowStyle.AddAttributesToRender (writer, row);
-                               if ((row.RowState & DataControlRowState.Insert) != 0 && insertRowStyle != null)
-                                       insertRowStyle.AddAttributesToRender (writer, row);
-                                       
-                               row.RenderBeginTag (writer);
-                               
-                               for (int n=0; n<row.Cells.Count; n++)
-                                       row.Cells[n].Render (writer);
+                       if (table == null)
+                               return;
 
-                               row.RenderEndTag (writer);
-                       }
-                       table.RenderEndTag (writer);
+                       table.Render (writer);
                }
 
                PostBackOptions IPostBackContainer.GetPostBackOptions (IButtonControl control)
                {
-                       Control ctrl = control as Control;
-                       return new PostBackOptions(ctrl);
+                       if (control == null)
+                               throw new ArgumentNullException ("control");
+
+                       if (control.CausesValidation)
+                               throw new InvalidOperationException ("A button that causes validation in FormView '" + 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;
                }
 
        }