In order to create a ProxyNode that is observing the TopLabel of a particular other node, I provide a context menu item on the source node that puts an instance of the observing ProxyNode on the clipboard:
ProxyNode node = new ProxyNode(); node.Observee = TopLabel; GoCollection coll = new GoCollection(); coll.Add(node); view.CopyToClipboard(coll);
Setting ProxyNode.Observee adds the Proxynode instance to the observees observers:
public GoObject Observee { get { return _observee; } set { _observee = value; _observee.AddObserver(this); } }
In the CopyObject override of ProxyNode, the observee of the copy is also set:
public override GoObject CopyObject(GoCopyDictionary env) { ProxyNode copy = base.CopyObject(env) as ProxyNode; copy.Observee = this.Observee; return copy; }
After pasting from the view contextmenu, however, somehow another ProxyNode instance has been created/copied without using CopyObject (nor the constructor), as I can tell from the hashcodes.
As a result, the pasted object is not observing the node I wanted to create a proxy for, but something else, and the observer relationship does not work.
How can I make the observee survive a copy/paste operation ?
You’re probably talking about the deserialized ProxyNode that resides in the clipboard.
I think it might be wiser to update the Observee reference when the ProxyNode is added to your document, using some other kind of identifying information that is serialized/deserialized or copied, not by using a direct reference. This requires that you have some other way of identifying those other nodes that contain TopLabels.
I assume you have corresponding calls to RemoveObserver that get called appropriately, too, right? For example, you need to handle the cases when the Observee is replaced, as well as when the ProxyNode is removed from the document.
Yes, a dictionary, for example a hash table, is a common way to do this. Perhaps you already have some unique string that names the node.
You can override GoObject.OnLayerChanged to notice when the node is added to a document (layer) or removed from one. That’s true for both the ProxyNode as well as your other kind of node, assuming you want the code in the nodes rather than in a central place such as the document.
The clipboard contains a newly created instance of your document class, containing the selected/copied GoObjects.
So your override of OnLayerChanged can just look to see whether the GoLayer.Document property is one of "your" documents. You may need to do some initialization of your GoDocument (not in the constructor!) so that you can tell that it's one of your real documents, and not a temporary one.