Using CopyObject() and ISerializable


#1

I am using GoDiagram .NET 2.1.2 for WinForms. I have a base class “DiagramNode” that inherits from GoIconicNode and implements ISerializable.
I am trying to implement Cut/Copy/Paste, as well as Ctrl drag-copying, and am having trouble understanding the behavior of CopyObject() and it’s interaction with the ISerializable interface methods with these different types of copying.

With Ctrl drag-copying, CopyObject() only gets called once. While debugging in CopyObject(), it appears that “this” is the original object that is being copied “from”, and that base.CopyObject() returns the new object that is being copied “to”.
All fields in the new object have the identical value as the corresponding field in the original object. Fields that are references to objects must be new’d for the new object, otherwise both the old and new object would have references to the same instance.
The ISerializable interface methods are never called for drag-copying.

With clipboard Cut/Copy/Paste, here is the sequence I observe: On Cut/Copy, I only get a call to CopyObject(). On Paste, I get calls to 1) the ISerializable method GetObjectData(); 2) the ISerializable constructor; 3) CopyObject().
The CopyObject() during Cut/Copy appears to be the same as a drag-copy. “this” is the original source object, and base.CopyObject() returns a new object that appears to be an exact copy of the original, with fields that are object references being references to the same instances. I assume (but may be wrong), that this CopyObject is copying from my GoView’s Document to the Clipboard Document.
The CopyObject() during Paste, however, seems different. I assumed that it was copying from the Clipboard’s Document to my GoView’s Document, and that therefore “this” would be the object on the Clipboard Document and that base.CopyObject() returns the new object being pasted to my GoView’s Document. I am not sure if this is correct.
During the Paste CopyObject(), the call to base.CopyObject() returns a GoObject with null values for all of my member fields (fields that aren’t part of the GoIconicNode base class). If I initialized any of my fields in the ISerializable contructor, these values are shown in this object (rather than null).

Here are my questions:

  1. Is there any full documentation on how to use CopyObject(), CopyChildren(), and ISerializable with respect to Cut/Copy/Paste as well as Ctrl drag-copying? The GoUserGuide, GoFAQ, and Go Reference Manual do not answer these questions adequately.
  2. In the CopyObject() call which executes during Paste, does base.CopyObject() return the new object that is being pasted into the View’s Document?
  3. From within CopyObject(), is there an easy way for me to distinguish if I am in the middle of a “Ctrl drag-copy” rather than a “Paste” operation?
  4. Why are the ISerializable interface method GetObjectData and the ISerializable constructor not called during Cut/Copy – only during Paste?
    Thanks in advance for any assistance,
    -Darren

#2

That’s very good–you accurately describe both processes.
Drag-and-drop is a modal operation, so the original objects are always potentially available directly in memory for drops within the AppDomain. A drag-and-drop from one app to another will get serialized/deserialized. (Actually I haven’t confirmed exactly which circumstances will cause serialization; that’s handled by the drag-and-drop implementation.) The data is actually a GoSelection.
Copy and paste (in the full .NET Windows Forms) always involve the clipboard. CopyToClipboard makes a copy of the objects in a separate GoDocument, which is then made into a DataObject and sent to the clipboard by being serialized. The copied data will persist even if the original objects have been deleted. This copy then can be looked at by other applications as well. PasteFromClipboard then deserializes the document/objects, and then copies them into your view’s document. (So the answer to your question #2 is yes.)
I would recommend implementing ISerializable (if needed) in a different class, instances of which are referenced from your DiagramNode, rather than implementing it directly by DiagramNode. This avoids having to fit in with the standard serialization being done for the GoObjects such as your node.
(#3) I’m not sure there’s a good way to tell. If you can get to the right GoView, you might be able to tell, but off-hand I’m not sure. Of course, in version 2.2 you could override GoToolDragging.DoDragDrop to set some global state, so that you could know that a drag-and-drop is in progress.
(#4) I think you are asking about when deserialization happens. PasteFromClipboard does, as you know. GoView may also do so when accessing the GoSelection data during a drag or at a drop.