Can’t remove selection handles

We have a custom container node type. The bounds of this node are defined visually by a GoRectangle. When selected, we have code to add all nodes falling within the bounds to the container, recursive of course. This all has worked fine for some time.
We now want to not show selection rects for the contained nodes. If I RemoveSelectionHandles for each such node in the drag tool ComputeEffectiveSelection this works fine, but only while a drag is in progress of course. But we also want this to be the case when not dragging (when simply selected). But when computing the selection in the container node’s OnGotSelection, if I call RemoveSelectionHandles on a contained node, after adding that node to the selection, the selection handles are still displayed. Can you tell me how to get rid of individual selection rects within a given selection?

Override your node class’s GoObject.AddSelectionHandles to be a no-op if it is contained in your container, otherwise call the base method.

I have run this in the debugger and the overide of AddSelectionHandles does not appear to be called. For example, I overrode AddSelectionHandles in a node type deriving from GoIconicNode, and the override was never called no matter how the node was selected. Maybe I need to subclass the icon and override AddSelectionHandles on myImageObject?.

However even so this solution would not be ideal. For the node to know whether it should have a selection rect it must know if its container is selected. The contained node can be individually selected in which case it should show a selection rect. It is only when the container is selected that the contained nodes should have no rect. Asking a node’s container if it is itself selected to determine whether to show the node’s rect presents some problems, one being selection order during a SelectAll, there are others. Is there a way to simply tell a GoObject to erase its selection rect? Since I am adding nodes one at a time to a selection, at the time the container itself is selected, this would seem to be the logical spot to do this. I’ll be grateful for any ideas of course.

Oops, yes, I misspoke. I meant your node’s SelectionObject class’s AddSelectionHandles method. However, if you were not going to show any selection handles, you might find it more convenient to override AddSelectionHandles on the node class and also override GoObject.SelectionObject to just return the node itself, instead of returning the Icon.
But I see now that the selection indication behavior you want is more complicated. GoObject.RemoveSelectionHandles is supposed to do what it says, in contrast to and in conjunction with AddSelectionHandles. This behavior is independent of objects being added and removed from the GoView.Selection collection. You just need to update the handles as objects are added or removed from the GoView.Selection. That’s easy if you implement GoView.ObjectGotSelection and ObjectLostSelection event handlers:
private void myView_ObjectGotSelection(Object sender, GoSelectionEventArgs evt) {
GoObject obj = evt.GoObject;
// remove handles from all children, recursively
RemoveChildrenHandles(myView.Selection, obj);
// and also remove from this object if any parent is selected
if (IsParentSelected(myView.Selection, obj.Parent)) {
if (obj.SelectionObject != null) {
obj.SelectionObject.RemoveSelectionHandles(myView.Selection) ;
}
}
}
private bool IsParentSelected(GoSelection sel, GoObject obj) {
if (obj == null) return false;
if (sel.Contains(obj)) return true;
return IsParentSelected(sel, obj.Parent);
}
private void RemoveChildrenHandles(GoSelection sel, GoObject obj) {
GoSubGraph sg = obj as GoSubGraph;
if (sg != null) {
foreach (GoObject child in sg) {
RemoveChildrenHandles(sel, child); // recurse unconditionally
// if this child is selected, remove any handles
if (sel.Contains(child) && child.SelectionObject != null) {
child.SelectionObject.RemoveSelectionHandles(sel);
}
}
}
}
private void myView_ObjectLostSelection(Object sender, GoSelectionEventArgs evt) {
// add handles to any selected children, recursively
RestoreChildrenHandles(myView.Selection, evt.GoObject);
}
private void RestoreChildrenHandles(GoSelection sel, GoObject obj) {
GoSubGraph sg = obj as GoSubGraph;
if (sg != null) {
foreach (GoObject child in sg) {
// this child is selected and visible – add its handles again
if (sel.Contains(child) && child.CanView() && child.SelectionObject != null) {
child.SelectionObject.AddSelectionHandles(sel, child);
} else { // if this child is not selected, search its children for any
RestoreChildrenHandles(sel, child);
}
}
}
}
So I don’t think you need to override any methods on any class.

Did the above code implement the kind of selection indication behavior you wanted?