Error with Dynamanic List and Sorting Lists

Error with Dynamanic List and Sorting Lists

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


harrybow5 posted on Monday, May 20, 2013

Hello,

I am experiencing a problem with CSLA that didn't seem to be in the forums, until last week when someone else was experiencing the same problems as me. the post the question is in is marked with a suggested answer so this might be the reason why you have not seen it. however I am reposting it here in hope for a answer.

---------------------------------------------------------------------------------------------------------------------------------------------------------

 Original Post from  Cymro in forum post Error when pressing escape key on a filtered list bound datagridview

---------------------------------------------------------------------------------------------------------------------------------------------------------

I have tested this further and it appears that there are other issues around the CancelNew behaviour with a DataGridView.  The reason I was looking at this was because we are attempting to use a SortedBindingList and FilteredBindingList with a DynamicBindingListBase derived class.  The issue here is that when the list is Sorted (or filtered) the cancel new fails and leaves the invalid new item in the list.

I have tracked this down and found the issue but not a satisfactory resolution Tongue Tied

When a new row is added to a DataGridView the AddNew adds the object to the end of the list.  Even if the sorted is list is sorted it still goes at the end of the sorted list (which is what we want).

The issue is with the way that the DataGridView's DataBinding handles the cancelling. 

  1. The DataGridView calls CancelEdit on the child object through (IEditableObject.CancelEdit). 
  2. The changes get rolled back in the child object, but this has the side effect of raising OnUnknownPropertyChanged.
  3. PropertyChanged is handled by the parent BindingList and raises the IBindingList.ListChanged event with a ListChangeType of "Reset". 
  4. The SortedBindingList handles the ListChanged of the source list and calls DoSort, resorting all the items in the list (including the new item).  This is where the problem lies!!!
  5. The DataGridView then calls ICancelAddNew.CancelNew passing the last row index - but this is no longer where our item is, because it has been re-sorted into the middle of the list somewhere.

We do not see the effect of this issue in a BusinessBindingListBase because as part of the CancelEdit on the child, it calls to the parent list to remove it (when the EditLevel < EditLevelAdded) using IParent.RemoveChild(T child).  With a BusinessBindingListBase the implementation of this method removes the child, whereas with a DynamicBindingList does not.  Therefore, with a BusinessBindingListBase the new child is removed from the list before the CancelNew is even called (as part of step 2 above) which masks the issue with the CancelNew implementation of the SortedBindingList.

I am unhappy with this "fix" for two reasons. Firstly, the original comment in the method...

...suggests that this was thought about and decided this should not be done here.  And secondly because this just masks the real issue of the list getting re-sorted during the whole cancel process.

Now the obvious "fix" is to have the DynamicBindingList remove the child as part of the IParent.RemoveChild implementation as follows...

    /// <summary>
    /// This method is called by a child object when it
    /// wants to be removed from the collection.
    /// </summary>
    /// <param name="child">The child object to remove.</param>
    void Core.IEditableCollection.RemoveChild(Csla.Core.IEditableBusinessObject child)
    {
      Remove((C)child);
    }

I am unhappy with this "fix" for two reasons. Firstly, the original comment in the method...

      // do nothing, removal of a child is handled by
      // the RemoveItem override

...suggests that this was thought about and decided this should not be done here. And secondly because this just masks the real issue of the list getting re-sorted during the whole cancel process.  Does anyone have any thoughts?

---------------------------------------------------------------------------------------------------------------------------------------------------------

EDIT:

---------------------------------------------------------------------------------------------------------------------------------------------------------

Forgot to mention that I am using CSLA 4.0.1 and have also tried this on 4.2.something

harrybow5 replied on Wednesday, June 12, 2013

Its been a few weeks and no reply on this which was a bit gutting as I really wanted to use the dynamic list.

however I did find a work around of such, I have implemented a editable root list and made it act as a dynamic.

This wasn't what we really wanted to do however it does seem to of worked rather well.

Copyright (c) Marimer LLC