Page 1 of 1

Newbie question on picture instance names

Posted: Wed Dec 12, 2012 2:17 pm
by LHuisingh
I am just starting out with VG.Net and the trial version. I have created a Picture class that I want to place instances of on several different forms and canvases. Each instance of my component will be individually and uniquely named. My goal is to be able to have the Click event of the Picture know what the name of the clicked instance is. As of now, I have named the Picture "Sensor" and I have set SerializeNames to true. In my Click event I have the following code:

Code: Select all

        private void Sensor_Click(object sender, InputEventArgs e)
        {
            Sensor sens = (Sensor)sender;
            if (sens != null)
            {
                Console.WriteLine("Sensor_Click {0}", sens.Name);
            }
        }
The output shows "Sensor_Click Sensor" indicating the Name property is the name of the Picture Class rather than the instance (set in this particular case to "sensor1"). Can I query the instance in this code to know which instance I clicked? I will admit that I'm still learning the object model so I might be missing something very basic.

Thanks for any help.

Re: Newbie question on picture instance names

Posted: Wed Dec 12, 2012 5:16 pm
by Frank Hileman
Hello Larry,

Please check the *.Designer.cs file to see if the Name property values were correctly serialized. If SerializeNames is set to true, you should see the code setting the Name property values. If not set, the Name of an Element is the empty string.

Your code is exactly correct, except if you are trying to distinguish across Canvases, you may have duplicate names by design. Also, if you are detecting the event on a parent object, you will need to dig into the InputEventArgs.AffectedElements property, where you can access the whole stack. The first Element is the leaf, and the remaining are ancestors in order.

Regards,

Re: Newbie question on picture instance names

Posted: Wed Dec 12, 2012 5:31 pm
by Frank Hileman
Hi Larry,

OK thinking about this I have a theory. You are catching the event at the level of the component. It is a top-level Picture. The top-level Picture has a name, however it will always be the same, as it is not a sub-Picture. When you add it to a Canvas dynamically it's name does not change. In that case you need to set the Name explicitly in the code when you add it to the Canvas. Perhaps I am correct?

And the same diagnosis would be true for a dynamically added sub-Picture.

Regards,

Re: Newbie question on picture instance names

Posted: Thu Dec 13, 2012 8:22 am
by LHuisingh
I checked the *.designer.cs file and the .Name property is being set on the Sensor class.

Also, I am incorporating this Sensor component on another Picture which contains an image and a polygon or two. Finally, this Picture is placed on a canvas in a form. I imagine I will ultimately be having a few hundred pictures each with their own images, polygons and Sensor components.

I was able to access the InputEventArgs.AffectedElements collection. The only Name values I received were the generic names as created in the component design. Is there a way to give each instance of a component a name and a text value such that the Click method can do instance-specific actions? Likewise, I would like to have each instance of the component have a unique ImageFill. Is this possible?

Re: Newbie question on picture instance names

Posted: Thu Dec 13, 2012 9:51 am
by Frank Hileman
Hi Larry,

When you add things in the designer, they are forced to have unique names. This is a requirement. If those names are serialized, the names are unique, within that Picture. I think you are seeing the name that is serialized by default for a top-level Picture, not a sub Picture. If your sub Pictures is added dynamically, you have to generate a unique name when you add it. You can also set the Tag property if you wish, to a string or any other object.

If your Sensor is added to another Picture, as a sub-Picture, in the designer, it already has a unique name, as long as SerializeNames is set to true on the parent Picture. If not, it will continue to use its original name.

You can generate a unique name for dynamically added items by using a static integer field that is incremented for each new name, and converting that to a string, with some kind of prefix you would like for debugging.

By default the Fill value on an Element is null. Fill objects are never shared. If you want to share one, it is use a Style, and set the Style property on each Element. If you never want to share one, you must create one explicitly for each Shape. If they are only defined dynamically, it is best to do this at run-time. No point in creating them in the designer. I probably need more information to make a better recommendation.

If you are only setting the ImageFill in your event handler, you can check to see if the Fill property refers to an ImageFill. If not, create a new ImageFill. If so, modify the one you have.

Code: Select all

Shape shape = sender as Shape;
if (shape != null)
{
    ImageFill imageFill = shape.Fill as ImageFill;
    if (imageFill == null)
    {
        imageFill = new ImageFill();
        // ... initialize imageFill ...
        shape.Fill = imageFill;
    }
    // ... modify imageFill ...
}
Regards,

Re: Newbie question on picture instance names

Posted: Thu Dec 13, 2012 10:25 am
by LHuisingh
I had set SerializeNames to true on the component level class. I had not set SerializeNames to true on the containing Picture. Once I did so on the Picture containing the instance of the component, the Click handler could correctly retrieve the name of the specific component instance. As it turns out, I may not even need SerializeNames turned on for the component if I only care about the instance-specific name as found on its containing Picture.

Learning as I go.