So one of the developers on my team asked me to override CSLA child delete behavior. His suggestion was:
Can anyone think of a reason to not do this?
Why wouldn't root objects be able to be deleted? That's a perfectly valid thing to do.
Also, a child doesn't necessarly have to belong to a list to be a child; it may represent optional information which can be deleted.
My question is why would you WANT to restrict deletes to only children in a list?
The thought here is that if the child belongs to a list, we want the delete operation (of off the child) to remove itself from the parent list.
nothing special needs to happen if the BO is a root object (root objects can and should just delete themselves... I haven't given much thought to the EditableRootList scenerio...hmmm)
nothing special needs to happen if the BO is not a member of a list (BOs that are Children of another BusinessBase can and should be dealt with through normal processing... I think).
regarding your last question...my mistake, the last else should be
base.Delete();
Ok, that makes a bit more sense then, but I'm still not sure what you're trying to do.
If you want to remove an object from the parent list, why wouldn't you just call Remove on the parent list? Databinding expects you to call Remove, so going your route I think would confuse databinding.
I'm with Andy... BB objects that are children of a BusinessListBase can't be deleted "on their own". Explicitly calling the "Delete" method on a child object already throws an exception. So in what case would the delete functionality be executed on a child BB object that didn't originate from its parent list? And what would you gain by allowing this to happen?
- Scott
I would have to dig back into the use case again (it has been on my plate for a while and I am just now getting back to it). From what I can remember, the ViewModel did not have access to the parent list... but I could be wrong. I will post back to this thread when I get a chance to refresh my understanding of the use case again.
As far as messing up databinding, I don't think this will be a problem (at least in silverlight... and probably in winforms as well). If I understand correctly, the fact that the remove is being called from the child should be irrelivant to databinding. Whether remove is executed from the UI layer (databinding, codebhind, viewmodel, etc.) or from the business layer the remove *should* behave the same.
Well, I'm not sure about Wpf, but it certainly would screw up WinForms databinding. The problem would be that you've basically yanked away the databound object without the UI knowing about it... so it thinks its still there. From there, bad things happen..
To my knowledge though, a grid in Wpf should behave like a WinForms one; it should ask the collection to remove the specified item. At least, that's how the grids behave when I've been working in wpf.
am_fusion:
if this.IsChild is true
-- if this.parent is business list base
---- execute parent.Remove(this)
Yes, in Windows Forms 1.x data binding, when a row was removed from a datagrid binding would tell the child to remove itself from the collection. So CSLA had (and has) code to allow the child to talk to the collection and ask the parent collection to remove the child. Of course that just moved the child to the deletedList.
In Windows Forms 2.0+ data binding is a lot better, and directly talks to the collection to remove the child.
In CSLA 4.0 I'll probably remove the ugly code for 1.x support - I surely hope people using .NET 4.0 aren't still using old 1.x style data binding :)
So CSLA currently has code that allows the child to talk to the collection and ask the parent collection to remove the child? I haven't found any code like this. I don't supose you remember where this code is off the top of your head?
When I think about the behavior we are describing here, it seems to me that we should be ok since databinding is responding to NotifyCollectionChanged\ListChanged event neh? In other words, when a child is removed from the list via code, the UI element updates its state by listening to the NotifyCollectionChanged\ListChanged. It shouldn't care who executed the remove. Is there something I am not understanding correctly?
I hope to sepend some time with the developer who original requested this change to better understand why they can't use the collection directly to do the remove.
am_fusion:When I think about the behavior we are describing here, it seems to me that we should be ok since databinding is responding to NotifyCollectionChanged\ListChanged event neh? In other words, when a child is removed from the list via code, the UI element updates its state by listening to the NotifyCollectionChanged\ListChanged. It shouldn't care who executed the remove. Is there something I am not understanding correctly?
Again, I'm not sure about Wpf, but in WinForms this certainly isn't the case. You get into all sorts of problems unless you ask the BindingSource component to remove the item (via its Remove method). Going directly to the BusinessListBase collection and calling remove screwed up the databinding. Even then I'm not sure it always worked right, and I tend to favor asking the grid to remove the row (which then triggers the proper databinding stuff).
am_fusion:I hope to sepend some time with the developer who original requested this change to better understand why they can't use the collection directly to do the remove.
I'd be curious to know too.. I would think the grid and databinding should be handling it.. even if you're just asking a grid to remove programatically.
am_fusion:So CSLA currently has code that allows the child to talk to the collection and ask the parent collection to remove the child? I haven't found any code like this. I don't supose you remember where this code is off the top of your head?
It is buried deeply in the n-level undo implementation, and is tied into the IEditableObject interface implementation as well.
There' only one way to trigger this behavior, and it is by emulating (or using) Windows Forms 1.x datagrid binding behavior.
And honestly it was a terrible thing to do. It complicated the heck out of the IEO implementation and was the source of many headaches. .NET is generally designed under the assumption that the collection will be told to remove an object, not a child object, and 1.x data binding went against that model - thus causing pain.
This is why 2.0 data binding fixed the issue - because everyone involved realized how bad an idea the 1.x design really was.
My recommendation is to not emulate that mistake :)
I've overriden the delete method in a child business object to remove itself from the collection as follows:
public override void Delete()
{
CanExecuteMethod("Delete", true);
this.Parent.RemoveChild(this);
}
I mainly use the child delete method when working with tree structures wrapped in ViewModel objects.
Will the RemoveChild() method be abandoned in CSLA 4.0?
I don't know that I'll get rid of RemoveChild() necessarily. The part I want to get rid of in 4.0 is the code in the IEditableObject implementation that tracks whether the child is new so it knows to call RemoveChild() when CancelEdit() is called on a new/unchanged child object.
And honestly, even that is just cleanup, and so falls pretty low on the priority list.
Copyright (c) Marimer LLC