Selection cleared on unload

It looks like the diagram selection is cleared as the diagram is getting unloaded from the visual tree. This is problematic when your diagram is inside of a TabControl and you’re propogating the selection to an external selection manager. Here’s what happens in Silverlight when you switch tabs:

TabControl.Unloaded fires
Diagram runs internal Unloaded event handler
Selection is cleared, causing a Diagram.SelectionChanged event (this is where my external selection manager gets screwed)
Diagram.Unloaded fires

The internal Unloaded event handler will always be first in the list of delegates so the selection will always be cleared. I suppose I could set Diagram.UnloadClearsPartManager=True, but I was hoping to actually unload all of those parts and potentially regain some memory. Is it possible in the next release to either not clear the selection when unloading or provide a flag similar to UnloadClearsPartManager (say, UnloadClearsSelection) that prevents that behavior while still allowing the PartManager to be cleared?

I was able to work around this using a pair of Blend SDK behaviors that use the Prism messaging channel, but its fairly convoluted and seems fragile.

I don’t understand what’s going on in your situation.

If the Diagram can tell that it’s in the visual tree of a TabControl at the time of the Unloaded event, it will not clear the PartManager and remove all of the Parts. So you shouldn’t be losing the selection.

If for some reason the Diagram is incorrectly deciding that it is not inside a TabControl, you can explicitly set Diagram.UnloadingClearsPartManager to false to prevent the clearing of the Parts from the Diagram. Again, then you will not be losing the selection.

The problem with what you suggest, in the case where the clearing of Parts actually does happen, is that removing a selected Part necessarily means that it can’t be in the Diagram.SelectedParts collection any more if it doesn’t exist. Sure, we could add functionality to try to restore the selection when reloading, but that wouldn’t help your particular issue of temporarily losing the selection.

A better alternative would be for us to not remove selected Parts from the Diagram when it’s unloaded. The problem is that that would not remove the data-bindings which would otherwise cause memory leakage. So we can’t do that.

Sorry, I keep forgetting that the Diagram knows if it’s a TabControl and then behaves differently. My Diagram is inside of a Telerik RadPane which is functionally similar to a TabControl, but does not derive from TabControl. Hence I would have to tell it to behave differently by setting UnloadingClearsPartManager=False.

I’m happy to let the PartManager get cleared and then rebuilt when I switch away from and then back to the tab which contains my Diagram. I suspect the memory usage for my application will be improved if I allow this to occur. The only thing about which I am unhappy is that GoXam does not provide a mechanism to let me figure out that a particular SelectionChanged event is due to the Diagram unloading. Something simple such as a Diagram.IsUnloading read only property which I could check or an IsUnloading event which gets raised as the very first step in an unload scenario would be perfect. (The property would allow me to check if I should run my logic; the event would allow me to detach my event handlers before things like SelectionChanged are raised.)

Right now my only solutions are to set UnloadingClearsPartManager=True (which will increase my already largish memory footprint) or the hackish workaround with the two behaviors and Prism event aggregator. I was hoping for a better solution in the next release.

I suggest you implement Unloaded and Loaded event handlers on the Panel containing the Diagram. In those event handlers you can disable your code that handles selection changes. You can also remember enough information about the selection to be able to restore the selection in the Loaded event handler. As I said earlier, you won’t want to keep references to Parts. But you could try keeping references to the model data.

I hope this strategy will work for you.

Thanks, that worked.