DataGridView Error on Delete

DataGridView Error on Delete

Old forum URL: forums.lhotka.net/forums/t/4004.aspx


strick9 posted on Friday, December 07, 2007

Howdy All,

I have exhausted my search for my issue and while finding plenty of discussion, I have not seen the applicable solution.  Time for the direct approach…


I am trying to mimic the RoleEdit/Roles/Role scenario in the Project Tracker demo as closely as possible in a simple business object list testing application.  The goal is to be able to switch the BO bound to a BindingSource and then test the CRUD functions in a DataGridView control.  I have “CRU” working but when I hit the Delete key on a row, I get the following error…


  The following exception occurred in the DataGridView:

    System.IndexOutOfRangeException: Index 3 does not have a value.

      at System.Windows.Forms.CurrencyManager.get_Item(Int32 index)

      at System.Windows.Forms.DataGridViewDataConnection.GetError(Int32 rowIndex)

    To replace this default dialog please handle the DataError event.


I placed stops in the form and list object code, but the error occurs as soon as I hit the key, so I feel this is something to do with my object or form setup.  When I do this in the Project Tracker demo, the row drops from the grid/gets deleted when the save routine is run.


I am using a VB WinForm project with CSLA 3.x.  Any pointers to the right place to diagnose this would be appreciated.  Let me know if there are any other specifics I can provide.


Thanks

Brian

praevsky replied on Saturday, December 08, 2007

Did you delete the last record?
I would guess that if go into SQL Server Management Studio, and add a record by hand, you'll be surprised by the value of the primary key.
Class Role has an Id property whose get method looks fishy to me under those circumstances.

    public int Id
    {
      [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
      get
      {
        CanReadProperty(true);
        if (!_idSet)
        {
          // generate a default id value
          _idSet = true;
          Roles parent = (Roles)this.Parent;
          int max = 0;
          foreach (Role item in parent)
          {
            if (item.Id > max)
              max = item.Id;
          }
          _id = max + 1;
        }
        return _id;
      }
      [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
      set
      {
        CanWriteProperty(true);
        if (!_id.Equals(value))
        {
          _idSet = true;
          _id = value;
          PropertyHasChanged();
        }
      }
    }

praevsky replied on Saturday, December 08, 2007

Oops.  To be fair, the ID field in the Roles is not an auto-increment (Identity Specification) field.  I would guess that the ID field in your table is.

strick9 replied on Monday, December 10, 2007

Thanks for your reply.  I would have gotten back to you sooner, but I had a group of Scouts in the mountains over the weekend.

 

On the autonumber, I do not have one in my application.  The “row id” is entered by the user.  My data store is also not SQL Server, but a DB2 UDB running on an iSeries machine.


It is interesting that you brought up the last record, as that is what I am testing to delete (the specific error above), however, I get another error entirely when deleting the next to last record…

 

The following exception occurred in the DataGridView:

 

System.NotSupportedException: Invalid for root objects – use Delete instead

At Csla.Core.BusinessBase.DeleteChild()

At Csla.BusinessListBase ‘2.DeleteChild(C child)

At Csla.BusinessListBase ‘2.CopyToDeletedList(C child)

At Csla.BusinessListBase ‘2.RemoveItem(Int32 index)

At System.Collections.ObjectModel.Collection ‘1.RemoveAt(Int32 index)

At System.Windows.Forms.BindingSource.RemoveAt(Int32 index)

At System.Windows.Forms.CurrencyManager.RemoveAt(Int32 index)

At System.Windows.Forms.DataGridView.DataGridViewDataConnection.Delete.Row(Int32 rowIndex)

At System.Windows.Forms.DataGridView.ProcessDeleteKey(Keys keyData)

 

To replace this default dialog please handle the DataError event.

 

When I “OK” this dialog box, another pops up (over and over again) …

 

The following exception occurred in the DataGridView:

 

System.IndexOutOfRangeException: Index 4 does not have a value.

At System.Windows.Forms.CurrencyManager.RemoveAt(Int32 index)

At System.Windows.Forms.DataGridViewDataConnection.GetError(Int32 boundColumnIndex, Int32 columnIndex, Int32 rowIndex)

 

To replace this default dialog please handle the DataError event.

 

All of that may not be relivant, as I just found one difference that I have in my setup.  The constructor on my BusinessBase object does not use the MarkAsChild.  When I do, I get the following handled exception upon the click of the update button (the row is removed from the grid, hoorah) …

 

Csla.DataPortalException was unhandled

  Message="DataPortal.Update failed (System.NotSupportedException: Invalid operation - delete not allowed

   at Csla.Core.BusinessBase.DataPortal_DeleteSelf()

   at Qds.Types.GL.Company.FullEdit.DeleteSelf() in C:\QDSProjects\bill test business objects\bill test business objects\Qds.Types.GL.Company\FullEdit.vb:line 390

   at Qds.Types.GL.Company.FullEditList.DataPortal_Update() in C:\QDSProjects\bill test business objects\bill test business objects\Qds.Types.GL.Company\FullEditList.vb:line 105)"

  Source="Csla"

  StackTrace:

       at Csla.Core.BusinessBase.DataPortal_DeleteSelf()

       at Qds.Types.GL.Company.FullEdit.DeleteSelf() in C:\QDSProjects\bill test business objects\bill test business objects\Qds.Types.GL.Company\FullEdit.vb:line 390

       at Qds.Types.GL.Company.FullEditList.DataPortal_Update() in C:\QDSProjects\bill test business objects\bill test business objects\Qds.Types.GL.Company\FullEditList.vb:line 105

       at Csla.MethodCaller.CallMethod(Object obj, MethodInfo info, Object[] parameters)

       at Csla.MethodCaller.CallMethod(Object obj, String method, Object[] parameters)

       at Csla.Server.SimpleDataPortal.Update(Object obj, DataPortalContext context)

       at Csla.DataPortal.Update(Object obj)

       at Csla.DataPortal.Update[T](T obj)

       at Csla.BusinessListBase`2.Save()

       at Qds.Types.GL.Company.FullEditList.Save() in C:\QDSProjects\bill test business objects\bill test business objects\Qds.Types.GL.Company\FullEditList.vb:line 96

       at BOGridTestr01.Form1.UpdateButton_Click(Object sender, EventArgs e) in C:\QDSProjects\BizObjTestr\BOGridTestr01\Form1.vb:line 16

       at System.Windows.Forms.Control.OnClick(EventArgs e)

       at System.Windows.Forms.Button.OnClick(EventArgs e)

       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)

       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)

       at System.Windows.Forms.Control.WndProc(Message& m)

       at System.Windows.Forms.ButtonBase.WndProc(Message& m)

       at System.Windows.Forms.Button.WndProc(Message& m)

       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)

       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)

       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)

       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)

       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)

       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)

       at System.Windows.Forms.Application.Run(ApplicationContext context)

       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()

       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()

       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)

       at BOGridTestr01.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81

       at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)

       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)

       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()

       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)

       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

       at System.Threading.ThreadHelper.ThreadStart()

 

I’m looking into resolving this issue now that I see the missing child setting.

 

Thanks,

Brian

strick9 replied on Monday, December 10, 2007

It appears that my troubles did indeed stem from not marking the BusinessBase as a child.  That was a conceptual missunderstanding on my part. 

I am now chasing down some other errors, however, I'll concider this issue closed as they appear to be related to my DataPortal code in the delete and will be though them shortly.

Thanks all,
Brian

ayubu replied on Monday, December 10, 2007

"

All of that may not be relivant, as I just found one difference that I have in my setup.  The constructor on my BusinessBase object does not use the MarkAsChild.  When I do, I get the following handled exception upon the click of the update button (the row is removed from the grid, hoorah) …

 

Csla.DataPortalException was unhandled

  Message="DataPortal.Update failed (System.NotSupportedException: Invalid operation - delete not allowed

   at Csla.Core.BusinessBase.DataPortal_DeleteSelf()

 

"

My words

You have done correctly but the issue here is that when you mark a object with "MarkAsChild" it can not be deleted by the DataPortal_DeleteSelf(This is called by the Dataportal for the parent object"

Then you need to implement the delete code for the child in a child collection and let those code be executed by calling then in the DataPortal_DeleteSelf of the object to this child belong

alex@alexw.co.uk replied on Wednesday, August 24, 2011

I would like to reply to this in case I forget the answer in the future and need this as a reference. Nowhere else on the net seems to have it.

I got this error when I forgot to change the RaiseListChangeEvents back to True after I'd disabled it (CSLA 3.8+). Correct code highlighted below:

        Protected Overloads Sub DataPortal_Fetch()

            RaiseListChangedEvents = False

            Using ctx = Csla.Data.ContextManager(Of LinqDAL.Call2FieldDataContext).GetManager(My.Settings.ConnectionStringName)

                Dim data = (From o In ctx.DataContext.DBUserProfiles Select o).ToArray()

                For Each element As LinqDAL.DBUserProfile In data

                    Me.Add(UserProfileListItem.GetUserProfileListItem(element))

                Next

            End Using

            RaiseListChangedEvents = True

        End Sub

 

Copyright (c) Marimer LLC