New tests.
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / FormView.cs
index 608893f4bb638de7034ef294f55c970a9875d584..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;
@@ -87,18 +88,18 @@ namespace System.Web.UI.WebControls
                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;
@@ -178,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)
@@ -218,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)
@@ -242,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)
@@ -258,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"));
                }
                
                
@@ -438,7 +464,7 @@ namespace System.Web.UI.WebControls
                [Browsable (false)]
                public virtual ITemplate EditItemTemplate {
                        get { return editItemTemplate; }
-                       set { editItemTemplate = value; RequireBinding (); }
+                       set { editItemTemplate = value; }
                }
 
                [WebCategoryAttribute ("Styles")]
@@ -479,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)]
@@ -512,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)]
@@ -590,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)]
@@ -627,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")]
@@ -652,7 +678,7 @@ namespace System.Web.UI.WebControls
                [Browsable (false)]
                public virtual ITemplate ItemTemplate {
                        get { return itemTemplate; }
-                       set { itemTemplate = value; RequireBinding (); }
+                       set { itemTemplate = value; }
                }
                
                [BrowsableAttribute (false)]
@@ -661,6 +687,9 @@ namespace System.Web.UI.WebControls
                        get {
                                return pageCount;
                        }
+                       private set {
+                               pageCount = value;
+                       }
                }
 
                [WebCategoryAttribute ("Paging")]
@@ -671,9 +700,9 @@ namespace System.Web.UI.WebControls
                                return pageIndex;
                        }
                        set {
-                               if (value < 0)
+                               if (value < -1)
                                        throw new ArgumentOutOfRangeException ("PageIndex must be non-negative");
-                               if (pageIndex == value)
+                               if (pageIndex == value || value == -1)
                                        return;
                                pageIndex = value;
                                RequireBinding ();
@@ -712,13 +741,12 @@ 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)]
@@ -765,7 +793,6 @@ namespace System.Web.UI.WebControls
                [BrowsableAttribute (false)]
                public virtual object DataItem {
                        get {
-                               EnsureDataBound ();
                                return dataItem;
                        }
                }
@@ -814,9 +841,10 @@ namespace System.Web.UI.WebControls
                
                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 ()
@@ -833,7 +861,17 @@ namespace System.Web.UI.WebControls
 
                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 ()
@@ -846,7 +884,7 @@ 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;
@@ -860,42 +898,64 @@ namespace System.Web.UI.WebControls
                                }
                        }
 
-                       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);
+                       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);
@@ -912,26 +972,28 @@ namespace System.Web.UI.WebControls
                                        itemRow = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
                                        break;
                                }
-                               table.Rows.Add (itemRow);
                                InitializeRow (itemRow);
+                               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) {
+                       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 ()
@@ -964,32 +1026,45 @@ 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);
@@ -1003,9 +1078,9 @@ namespace System.Web.UI.WebControls
                                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;
                                }
                        }
@@ -1037,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;
@@ -1052,12 +1128,6 @@ namespace System.Web.UI.WebControls
                
                public sealed override void DataBind ()
                {
-                       if (CurrentMode == FormViewMode.Insert) {
-                               RequiresDataBinding = false;
-                               PerformDataBinding (new object [] { null });
-                               return;
-                       }
-
                        cachedKeyProperties = null;
                        base.DataBind ();
                        
@@ -1124,14 +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);
                }
@@ -1139,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)
                        {
@@ -1192,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:
@@ -1212,7 +1295,7 @@ namespace System.Web.UI.WebControls
                                break;
                                        
                        case DataControlCommands.InsertCommandName:
-                               InsertItem (true);
+                               InsertItem (causesValidation);
                                break;
                        }
                }
@@ -1221,34 +1304,42 @@ namespace System.Web.UI.WebControls
                {
                        FormViewPageEventArgs args = new FormViewPageEventArgs (index);
                        OnPageIndexChanging (args);
-                       if (!args.Cancel) {
-                               int 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)
@@ -1258,8 +1349,8 @@ namespace System.Web.UI.WebControls
                
                void UpdateItem (string param, bool causesValidation)
                {
-                       if (causesValidation && Page != null)
-                               Page.Validate ();
+                       if (causesValidation && Page != null && !Page.IsValid)
+                               return;
                        
                        if (currentMode != FormViewMode.Edit) throw new HttpException ("Must be in Edit mode");
 
@@ -1269,15 +1360,14 @@ namespace System.Web.UI.WebControls
                        
                        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)
@@ -1286,7 +1376,7 @@ namespace System.Web.UI.WebControls
                        OnItemUpdated (dargs);
 
                        if (!dargs.KeepInEditMode)                              
-                               EndRowEdit ();
+                               EndRowEdit (true, false);
 
                        return dargs.ExceptionHandled;
                }
@@ -1298,23 +1388,22 @@ namespace System.Web.UI.WebControls
                
                void InsertItem (string param, bool causesValidation)
                {
-                       if (causesValidation && Page != null)
-                               Page.Validate ();
+                       if (causesValidation && Page != null && !Page.IsValid)
+                               return;
                        
                        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)
@@ -1323,7 +1412,7 @@ namespace System.Web.UI.WebControls
                        OnItemInserted (dargs);
 
                        if (!dargs.KeepInInsertMode)                            
-                               EndRowEdit ();
+                               EndRowEdit (true, false);
 
                        return dargs.ExceptionHandled;
                }
@@ -1336,21 +1425,22 @@ namespace System.Web.UI.WebControls
                        FormViewDeleteEventArgs args = new FormViewDeleteEventArgs (PageIndex, currentEditRowKeys, currentEditNewValues);
                        OnItemDeleting (args);
 
-                       if (!args.Cancel) {
-                               if (PageIndex > 0 && 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)
                {
@@ -1359,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;