So I have been trying to figure out the best way to go about this but always end up hitting a wall somewhere.
Basically, my problem is this: I have a layer that can draw items of the type UIElement. In my case, I need to be able to draw UIElements of two types, Image and Shape. They are both inherited from UIElement.
Now I want to create a class of my own, lets call the class a LayerItem. The LayerItem contains some additional information about the specific item, such as the name.
My first solution was to inherit the LayerItem from the Image-class and add the new fields. This way I was able to also catch all the events that the Image-object received (for example MouseOver) and then cast the object to LayerItem for the retrieval of the extra related information. Showing the image was accomplished by setting the object's Source-property.
This approach, however, does not work if the objects can also be shapes, since shapes do not have the Source-property.
Basically what I am looking for is "the right way" to accomplish this, in a way that allows me to use the events directly. Only solution I can currently come up with is to have a dictionary mapping the UIElements to the LayerItems, then fetching the LayerItem from there by the use of the UIElement whose event was raised. So, are there some better, perhaps more sophisticated ways of accomplishing this?
EDIT:
Thanks for the reply, but I'm not sure that's exactly what I am looking for. Let me try to clarify. Basically, I have a layer that I can draw different things on (Images or Shapes) by adding the graphic in question onto the layer and giving it coordinates.
The idea is that the user can click on the layer and choose from a list of things what kind of a graphic he/she would like to use to represent the added item. The extra information about the item, such as id and name, are stored in a databas开发者_如何学Ce and I need a way to link this information to the graphical item.
So all of this would be handled by code, the items are created and deleted dynamically. This is also where the events come in. To be able to recognize which item the user clicked (to show the extra information, allow drag-n-drop etc), I think the events produced by the UIElement are the easiest to use.
And about providing code as an example, well that's slightly hard because it depends a lot on the implementation :) But I surely can try and put something up if my explanation still isn't clear enough!
I would start by making a LayerItem descendant of UIElement, and then make all other needed classes descendants of LayerItem. Final hierarchy would look like this:
- UIElement
- LayerItem
- ImageLayerItem
- ShapeLayerItem
- etc.
And, if you want LayerItem to report any events from child-classes, then just have the event in LayerItem and let child-classes raise that event on their own events, like this:
class LayerItem
{
public string Name { get; set; }
public event EventHandler ItemEvent;
protected virtual void OnItemEvent(EventArgs e)
{
if (this.ItemEvent != null)
this.ItemEvent(this, e);
}
}
class ImageLayerItem : LayerItem
{
private Image _image;
public ImageLayerItem()
{
//here create Image element and think of rendering it.
_image = new Image();
//attach event handlers.
_image.Click += ... //don't forget to call LayerItem.OnItemEvent() inside the event handler.
}
}
Also:
- I would recommend having a special event handler type with corresponding special event arguments type in the LayerItem instead of just EventHandler and EventArgs. A good example would be LayerItemEventArgs which contains the name of event which was raised by one of the child classes (like ImageLayerItem) and its parameters. This way you can handle all the events by handling only the LayerItem.ItemEvent event; or you could just handle the events of child classes as a classical approach.
I hope this helps to be the head start where to go.
Seems like you could use attached properties for the extra information you want to store which your Layer needs.
A good example how this can be used is on the msdn page.
<DockPanel>
<CheckBox DockPanel.Dock="Top">Hello</CheckBox>
</DockPanel>
Checkbox
doesn't define the Dock
property, DockPanel
does. Any element can now set the Dock
property.
精彩评论