Port Image Not Copied/Pasted

I have assigned a custom image to a port(s). When the node is copied and then pasted, all the objects (including the ports) are copied, but the port.image(s) is missing?

Copy:
Paste:
Any ideas on this issue?

Can you post the code you use to add the image?

Dim img = New GoImage() img.Image = CType(GoImage.DefaultResourceManager.GetObject("true6"), Image) ap_true.PortImage = img

PortImage isn’t supported by GoPort, but is added in the sample MultiPortNode. Is that what you’re using?

What this does is

port.Object = img
port.Style = GoPortStyle.Object

I am using activityport, which adds a portimage.
Here is the full context:
Private ap_true As ActivityPort = New ActivityPort() 'object 6
'add True port Dim obbj As Object Dim pos As PointF Dim pos2 As PointF If (Not Me.Icon Is Nothing) Then pos = Me.Icon.Position Else pos = Me.Position obbj = ap_true If (TypeOf obbj Is ActivityPort) Then ap_true = CType(obbj, ActivityPort) If (Not ap_true Is Nothing) Then ap_true.UserFlags = PFPortType.pTrue 'this will be used to ID which port it is ap_true.MaxLinks = 1 ap_true.IsValidFrom = True ap_true.IsValidTo = False ap_true.FromSpot = GoObject.MiddleRight ap_true.ToSpot = GoObject.MiddleRight Dim img = New GoImage() img.Image = CType(GoImage.DefaultResourceManager.GetObject("true6"), Image) ap_true.PortImage = img ap_true.Size = New SizeF(25, 12) pos2.X = pos.X + Me.Icon.Width - 25 pos2.Y = pos.Y + 10 ap_true.Location = pos2 Dim i As Integer = Me.Count Insert(6, ap_true) End If

ok, you’re not adding the PortObject to the node or document, so it’s a shared object. The MemberwiseClone that happens on Copy should be fine then. In other words, your new node’s port should have PortObject/PortStyle set correctly. You should be able to check that in the debugger.

If that’s true, then it may be an ordering issue, where the Insert(6, ) works for the initial node, but not for the copy. (although as I type that, I can’t think why that would be)

Check your Port’s PortObject and PortStyle. If they look right, add some transparency to your node’s background object color and see if you see the port image poking through from behind.

The PortStyle is ‘Object {1}’

The PortObject is '{Northwoods.Go.GoImage}'
The image is not behind anything. I can move the port completely to the side of the node and the image is not there.

Here is another snapshot that shows the ports to the side (before and after):

ok, the port is the right size & location, or the links would be wrong.

is Port.Visible true? (again, I can’t imagine why it wouldn’t be, but I’m just looking for possibilities given the screenshots you’re posting)

Do you have an override for CopyObject? If yes, what does that look like?

I didn’t actually see anyplace in the samples where we use PortObject with a GoImage, so I tested that to be sure it works after a copy, and it does.

Port.visible = True

No override on CopyObject.

Can you test adding an image to an activityport?

I found another interesting behavior Jake.

When I cut/paste, the images disappear.
If I drag the node from one document to another, the images are preserved.

When I go to the Processor sample, and change ActivityPort.OnLinkChanged to:

      //this.Style = GoPortStyle.Triangle;    (OLD CODE)
      GoImage im = new GoImage();<span ="apple-tab-span"="" style="white-space:pre">	</span>// NEW CODE
      im.Name = "star.gif";<span ="apple-tab-span"="" style="white-space:pre">		</span>// star.gif was already a resource in processor
      this.PortImage = im;

it works when I copy these nodes.

If you want to send me your node/port code, I’ll see if I can see anything.

send to “godiagram”.

Jake

OK… you have a bunch of Private pointers in your node class. Those need some help on a copy.

You have to override CopyChildren. Look at the NodeLinkDemo sample, AutoLinkNode class with myAutoLinkingPort. You’ll have to copy that logic for each of your Private pointers. ColoredNode has another example.

Thanks Jake. I will take a look.

I have taken a look, and it is not making sense. I have 12 objects declared as private. 11.5 of them get copied. Only the images is missing. Does the copychildren override need to look like this (btw…this doesn’t work, but perhaps you might know why):

Protected Overrides Sub CopyChildren(ByVal newgroup As GoGroup, ByVal env As GoCopyDictionary) MyBase.CopyChildren(newgroup, env) Dim newnode As PFNode = CType(newgroup, PFNode) newnode.ap_next.PortImage = CType(env(ap_next.PortImage), GoImage) End Sub

Morning Jake,

Dim img = New GoImage() 'img.Image = CType(GoImage.DefaultResourceManager.GetObject("next_1"), Image) img.Name = "C:\...\Resources\next_1.png"
ap_next.PortImage = img
I got it to work by taking out the line of code that assigns the image from the ResourceManager, and replacing it with a fully qualified path for the image name. The image is copied and pasted.
I was hoping to take advantage of the ResourceManager's memory management (if it does what I think it does).

You override CopyChildren if you have a pointer in your node to an object that gets a new copy in the new node. so… a group holding an Icon, a Label, an InPort, and an OutPort might implement this
method as follows:

<code =“CS”>base.CopyChildren(newgroup, env);
MyNode newnode = (MyNode)newgroup;
newnode.myIcon = (GoObject)env[myIcon];
newnode.myLabel = (GoText)env[myLabel];
newnode.myInPort = (GoPort)env[myInPort];
newnode.myOutPort = (GoPort)env[myOutPort];
<code =“CS”>

<code =“CS”>The idea is you don’t want the newnode references pointing to the original node’s objects.
<code =“CS”>

<code =“CS”>Maybe I looked at your code too quickly, but I thought you had that situation.
<code =“CS”>

<code =“CS”>But… <code =“CS”>PortObject isn’t a child of the node, so it doesn’t get copied when the base CopyChildren makes a copy of each of the children. The reference should be copied… and that’s OK because of the unique way we handle PortObject. (In Port.Paint, we set the Bounds of the PortObject to the Bounds of the Port and then Paint it… that way the same PortObject can be shared across many ports.)
<code =“CS”>

<code =“CS”>Resource Manager optimizations really aren’t needed here.
<code =“CS”>

<code =“CS”>so… why does my test work and yours fail? and why does changing the “Name” to a full path fix it for you? Hmm. I am using “img.Name” and you were using “img.Image”, even though both of us were using the ResourceManager.
<code =“CS”>

<code =“CS”>Does it work for you if you do
<code =“CS”>

<font =“Apple-style-span” face=“monospace”> img.Name = “next_1”
<font =“Apple-style-span” face=“monospace”> ap_next.PortImage = im
<font =“Apple-style-span” face=“monospace”>

<font =“Apple-style-span” face=“monospace”>?

No. I had to use the fully qualified filename.

Well, I still want to understand this. Can you send me a new copy of your node and resource file you are using? thanks.