EditLevel problems with WinForms

EditLevel problems with WinForms

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


tetranz posted on Tuesday, January 22, 2008

Hi all

I thought and hoped EditLevel issues were behind me but unfortunately not quite :( .  I've been bashing my head with this and not getting far. I'm running CSLA 3.0.3 and following the ProjectTracker example for binding, rebinding, cancel etc. It all works well when I only have two levels, i.e, a root and child collection. Things don't go well with grandchildren. The problem is mostly if I delete a child and then Cancel.

I guess my basic question is:  Is there a systematic way of extending the binding stuff in ProjectTracker to three or more levels / generations?  The relationship between child and grandchild bindingsource mirrors what we do with root and child. i.e, the grandchild bindingsource's DataSource is set to the child bindingsource and its DataMember is set to the collection property of the child object. I'm a little unsure how to unbind the child bindingsource using the UnbindBindingSource() code. Is it considered a root as far as the grandchild collection is concerned?

I've done some tests monitoring EditLevel. To make this as simple as possible, there is only one child and its grandchild collection is empty. I've seen the same thing happening with grandchildren.

I'm reporting four EditLevel numbers in this order: root, child collection, child and grandchild collection.

Before the first BindUI()
0,0,0,0

After BindUI
2,1,2,1  (ProjectTracker does the same for the first three).

Now if I delete the child and then press cancel then before BindUI (i.e, after CancelEdit() on the root) I get 0,0,0,1. The root BeginEdit() in BindUI then fails with an Edit Level mismatch.

I think I need to get the grandchild collection down to zero (before the delete?) but I'm struggling to figure out how to do that.

I hate to say it but this was working on CSLA 3.0.0 with code similar to ProjectTracker 3.0.0

Thanks for any help
Ross

RockfordLhotka replied on Tuesday, January 22, 2008

I quickly updated my test project

(http://www.lhotka.net/cslacvs/viewvc.cgi/samples/trunk/RootChildGrandchildWinFormTest/)

to use the 3.0.3+ binding technique and I don't see a failure case there. Maybe I'm not doing something right as a user to make it fail. Can you use that as a test to replicate the issue?

tetranz replied on Tuesday, January 22, 2008

Thanks Rocky. I haven't used the SVN before but I'll give it a go.

RockfordLhotka:
I quickly updated my test project

tetranz replied on Tuesday, January 22, 2008

Rocky, I tried the test project and hit the problem immediately. I don't know if somehow my setup is different to yours but all have to do is run the project, delete a child and hit cancel. That gives me an edit level mismatch.

I couldn't edit the root name because of the null strings so I then modified the objects so that they have a non-zero incrementing id and non null name.

I can edit or delete a grandchild and bring it back with Cancel, no problem. Editing or deleting a child and then cancelling is a problem.

Ross

McManus replied on Tuesday, January 22, 2008

Ross,

We had a similar problem:

We found that if the Current item of bindingsource 2 changed, EndEdit() was not being called automatically on the Current (grandchild) item, leaving it at EditLevel 1. We solved this problem by calling EndEdit() ourselves. I don't know what event we hooked, but I can look that up if you're interested.

Hope this helps!

Cheers,
Herman

 

tetranz replied on Wednesday, January 23, 2008

McManus:
We found that if the Current item of bindingsource 2 changed, EndEdit() was not being called automatically on the Current (grandchild) item, leaving it at EditLevel 1. We solved this problem by calling EndEdit() ourselves. I don't know what event we hooked, but I can look that up if you're interested.

Thanks Herman. That sounds like the same problem I have. I think you probably used the CurrentChanged event but if you can confirm that some time I'd appreciate it. I've fiddled with similar "fixes" but I haven't had much luck with it. I guess it needs to do either an EndEdit or CancelEdit on the grandchild bindingSource depending on what you're actually doing. I've been concentrating on cancel simply because that's where I first noticed the problem.

Cheers
Ross

RockfordLhotka replied on Wednesday, January 23, 2008

Thanks! That does appear to be the solution.

What a PITA this all turns out to be...

tetranz replied on Wednesday, January 23, 2008

If this is working you then you're having better luck than I am Sad [:(].

I'm trying it on your test app Rocky by putting grandchildrenBindingSource.EndEdit() in childrenBindingSource_CurrentChanged. I think that's what Herman was suggesting. That seems to have made it work for saving after modifying a child but I've had no luck at all making cancel work after deleting a child. I tried CancelEdit instead of EndEdit without success. Unfortunately I'm at the limits of my understanding of how these bindingsources really work or at least are supposed to work.

Ross

McManus replied on Thursday, January 24, 2008

Ross, Rocky,

Apparently, calling grandchildrenBindingSource.EndEdit() in childrenBindingSource_CurrentChanged solved just a part of the problem. This call takes care of the fact that the EditLevel of the "Current" GrandChild item changes from 2 to 1 (which is a good thing!).

But there seems to be another problem: suppose we delete Child2. Just before the object is deleted, the value of BindingEdit is True. After deleting the object, the value of BindingEdit is still True.

Now, when we cancel the deletion, we first Unbind the bindingsources. This results in all objects being at EditLevel 1 (which is a good thing too!). Then CancelEdit() is called on the Root object. As a result, Child2 is added to the ChildList again. Both have an EditLevel of 0.

BUT: The GrandChildList of Child2 (and all its items) have an EditLevel of 1!!! The reason for this is that UndoChanges() wasn't called on the GrandChildList of Child2 ==> the result of BindingEdit having the value True.

When the root object is rebound again, EditLevelMismatchException is thrown.

 

The same problem occurs in the following sitation:

  1. Delete Child2
  2. Apply changes
  3. Change Name of the Root object
  4. Cancel the change

Note that the deletion of Child2 was confirmed, but canceling a new edit puts the deleted items back in the list again!!

Complex stuff, isn't it?!?!

Cheers,
Herman


tetranz replied on Thursday, January 24, 2008

Thanks Herman. That sounds familiar from my limited testing. I sat down to have another play with it at home last night and noticed that Rocky's test application in the svn has changed from the day before and has some more debugging in it so I think he's looking at it. Good luck Rocky Smile [:)] I'm sure it's time consuming at a awkward time and an absolute PITA to debug.

I only have this on one form and the n in n-level undo is never really > 1 for me so for now I've made the cancel button throw away the objects and reload from the db. That has solved my immediate problem.

Cheers
Ross

RockfordLhotka replied on Thursday, January 24, 2008

Grumble. I sent a response (possible fix) yesterday, but it appears to have disappeared between me and the forum :(

 

The solution appears to be in Core.BusinessBase. In the DeleteChild() method, add a “BindingEdit = false” line right before the MarkDeleted() call.

 

Can you test this in your scenarios and see if it does address the issue? (the EndEdit() call on the grandchild list is still required too)

 

Rocky

 

 

From: tetranz [mailto:cslanet@lhotka.net]
Sent: Thursday, January 24, 2008 11:28 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] EditLevel problems with WinForms

 

Thanks Herman. That sounds familiar from my limited testing. I sat down to have another play with it at home last night and noticed that Rocky's test application in the svn has changed from the day before and has some more debugging in it so I think he's looking at it. Good luck Rocky Smile <img src=">I'm sure it's time consuming at a awkward time and an absolute PITA to debug.

I only have this on one form and the n in n-level undo is never really > 1 for me so for now I've made the cancel button throw away the objects and reload from the db. That has solved my immediate problem.

Cheers
Ross

tetranz replied on Thursday, January 24, 2008

Yes, working perfectly. Big Smile [:D]  That's good news. I was worried that we might have to change the binding code in the UI forms again.

My real application uses a Janus grid with the children and grandchildren in a hierarchy so there's no grandchild bindingsource and that's working fine as is a more traditional test application I have.

Thanks
Ross

RockfordLhotka:
Can you test this in your scenarios and see if it does address the issue?

rkelley replied on Wednesday, May 21, 2008

Ross,

What do your BO's look like for your children and grandchildren. I am doing essentially the same thing you are except with an infragistics grid. When I add a child with grandchildren to the grid through code everything is fine. But, when I try to add records on the fly in the grid I get edit level mismatch on the grandchildren.

Did you just follow the same procedures for your grandchildren as you do for child objects?

Ryan

tetranz:
Yes, working perfectly. Big Smile [:D]  That's good news. I was worried that we might have to change the binding code in the UI forms again.

My real application uses a Janus grid with the children and grandchildren in a hierarchy so there's no grandchild bindingsource and that's working fine as is a more traditional test application I have.

Thanks
Ross

RockfordLhotka:

Can you test this in your scenarios and see if it does address the issue?

tetranz replied on Wednesday, May 21, 2008

rkelley:

Ross,

What do your BO's look like for your children and grandchildren. I am doing essentially the same thing you are except with an infragistics grid. When I add a child with grandchildren to the grid through code everything is fine. But, when I try to add records on the fly in the grid I get edit level mismatch on the grandchildren.

Did you just follow the same procedures for your grandchildren as you do for child objects?

Ryan

Hi Ryan
I'm not doing anything special. My form and bindingsources are as if there are no grandchildren and follow the project tracker example. I have two bindingsources, one for the root and one for the children. The children bindingsource is feed from the root in the normal way using the DataMember. The grandchildren stuff happens inside the Janus grid. The Janus designer lets me define a child table and set its DataMember to the name of the collection property on my child objects. Sorry, I don't have any bright ideas about you issue other than wonder if the Infragistics grid does something weird.

Ross

rkelley replied on Thursday, May 22, 2008

I believe that my issue lies in the fact that I am using managed (propertyinfo) fields for all of my properties including child object. It looks like if I take my child objects and convert them to private backed fields then this error will go away. I am in the process of testing this now.

RockfordLhotka replied on Thursday, May 22, 2008

Be aware that if you use private backing fields for your child objects that you’ll have to do all the manual property and event hookups that were necessary in CSLA 3.0, because you’ll lose all the features of automatic child management.

 

Rocky

 

 

From: rkelley [mailto:cslanet@lhotka.net]
Sent: Thursday, May 22, 2008 3:17 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: EditLevel problems with WinForms

 

I believe that my issue lies in the fact that I am using managed (propertyinfo) fields for all of my properties including child object. It looks like if I take my child objects and convert them to private backed fields then this error will go away. I am in the process of testing this now.

McManus replied on Friday, January 25, 2008

Rocky,

The fix in BusinessBase.DeleteChild, together with the EndEdit() call on the GrandChild object solve the problem.

Forget my remark about confirmed deletions showing up again. It doesn't happen now!

Cheers,
Herman

RockfordLhotka replied on Friday, January 25, 2008

Good, thanks!!

 

I’ve checked in that change to 3.0.4 and 3.5 in svn.

 

Rocky

 

 

From: McManus [mailto:cslanet@lhotka.net]
Sent: Friday, January 25, 2008 7:07 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: EditLevel problems with WinForms

 

Rocky,

The fix in BusinessBase.DeleteChild, together with the EndEdit() call on the GrandChild object solve the problem.

Forget my remark about confirmed deletions showing up again. It doesn't happen now!

Cheers,
Herman



Cosmin replied on Thursday, April 17, 2008

Hi,
Some more strange behaviour.

What if you have a collection in the root object but you don't bind it to any bindingsource. The edit level of the first child is 2 and after applying the changes the level 1(which is wrong) and it breaks next time I begin edit.

To fix it I just bound the collection to a hidden grid and let the binding framework do the work.

Is this a problem in the UndoableBase class? I'm using 3.0.4.

Thanks,
Cosmin

RockfordLhotka replied on Saturday, April 26, 2008

I’m not sure I follow what you are saying?

 

You have something like:

 

Person contains AddressList contains Address(*)

 

You don’t bind Person or AddressList but you do bind an individual Address?

 

Or you bind Person, but not AddressList, and then you do bind an individual Address?

 

Rocky

 

 

From: Cosmin [mailto:cslanet@lhotka.net]
Sent: Thursday, April 17, 2008 9:58 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: RE: EditLevel problems with WinForms

 

Hi,
Some more strange behaviour.

What if you have a collection in the root object but you don't bind it to any bindingsource. The edit level of the first child is 2 and after applying the changes the level 1(which is wrong) and it breaks next time I begin edit.

To fix it I just bound the collection to a hidden grid and let the binding framework do the work.

Is this a problem in the UndoableBase class?

Thanks,
Cosmin


Copyright (c) Marimer LLC