Remove Child from List & CSLA DataProvider

Remove Child from List & CSLA DataProvider

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


jnthomas posted on Friday, January 08, 2010

Hello,

I have a CSLADataProvider with an EditableBusinessList. I also have a Save button that is binded to the Provider. When I modify an object in my list, my Save button becomes enabled as expected.

My issue arises when I Remove an item from my list. I would expect my Save button to become enabled (as my list becomes dirty) but it doesn't.

When I started looking at the code for the CSLADataProvider, I noticed there was all the information for hooking up PropertyChanged, but I saw nothing in regards to ListChanged/CollectionChanged.

Am I doing something wrong or is this simply not implemented?

Thanks in advance.

RockfordLhotka replied on Friday, January 08, 2010

.NET or SL, and which version of CSLA?

jnthomas replied on Friday, January 08, 2010

Silverlight with CSLA version 3.7.1.0

jnthomas replied on Monday, January 11, 2010

Hello, just wondering if you guys have had a chance to look at this issue.

Thanks.

RockfordLhotka replied on Monday, January 11, 2010

I think this is fixed in 3.8, which listens for ChildChanged as well as PropertyChanged, and so should react to changes at any depth in the object graph.

jnthomas replied on Monday, January 11, 2010

ok I'll go try it and keep you updated.

jnthomas replied on Tuesday, January 12, 2010

Ok I've finished installing the 3.8.1 version and I'm receiving a variant of the original problem. The first time I remove an item, my Save button remains disabled, but when I remove a second item the Save button becomes enabled. Removing further items keeps the Save button enabled.

RockfordLhotka replied on Tuesday, January 12, 2010

I just created a test for 3.8.2 that does this:

        provider.ObjectInstance = custs;
        context.Assert.IsFalse(provider.CanSave, "CanSave should be false");
        provider.RemoveItem(custs[0]);
        context.Assert.IsTrue(provider.CanSave, "CanSave should be true");
        provider.RemoveItem(custs[0]);
        context.Assert.IsTrue(provider.CanSave, "CanSave should be true after second remove");

Where 'custs' is a CustomerList (BLB) that has just been retrieved with the data portal (Fetch). So it contains some objects, but starts out as IsDirty==false.

Notice how, after removing an item, CanSave is now true, because IsDirty is now true and IsValid is true and the user is authorized to do the save. In short, IsSavable is true.

This test passes.

The thing is, CslaDataProvider hasn't changed between 3.8.1 and 3.8.2. The 3.8.1 release is revision 4419, and the last change to CslaDataProvider was revision 4370 - somewhere before the 3.8.1 release.

In other words, you should have the latest code, and my test passes - which indicates some other problem in your case.

Can you look directly at the IsDirty/IsValid/IsSavable properties of the collection object itself? I am now suspecting that the collection isn't becoming savable as expected.

jnthomas replied on Tuesday, January 12, 2010

I just rechecked (it was something I had checked with 3.7.x) and the IsDirty/IsValid/IsSavable is equal to true.

But I did notice that the PropertyChanged value is "Cannot fetch the value of field 'PropertyChanged' because information about the containing class is unavailable." I'm not sure if that has anything to do with it.

jnthomas replied on Tuesday, January 12, 2010

I've done some digging in the RefreshCanOperationsValues() method and noticed that when I remove my first item targetObject.IsSavable is false. IsDirty is false as well. The thing is my List itself IsSavable = true. It almost seems like RefreshCanOperationsValues() is called before my List has finished removing the object and thus Is not even dirty yet.

jnthomas replied on Monday, January 18, 2010

I've done more research on this and have noticed that in your test scenario you are removing the item by using the provider, while in my scenario I am removing the item directly from the list.

When I remove the item by using the provider, my save button is correctly updated, but not when I remove by using the list. Unfortunately I cannot use the provider to remove an item (reason being completely out of the scope of this issue).

So the unit test would be something like:

provider.ObjectInstance = custs;
context.Assert.IsFalse(provider.CanSave, "CanSave should be false");
cuts.Remove(custs[0]);
context.Assert.IsTrue(provider.CanSave, "CanSave should be true");
cuts.Remove(custs[0]);
context.Assert.IsTrue(provider.CanSave, "CanSave should be true after second remove");

RockfordLhotka replied on Monday, February 01, 2010

I figured out the issue, and the fix will be in 3.8.3. It is in svn now

http://www.lhotka.net/cslacvs/viewvc.cgi/core/branches/V3-8-x/cslalightcs/Csla/Silverlight/CslaDataProvider.cs?view=markup

You can replace your CslaDataProvider code with the code from svn and give it a try - it should resolve the issue.

Thank you for helping to troubleshoot the problem, your input was very helpful!

Copyright (c) Marimer LLC