Hi,
I would like to be able to create a custom pin with a Usercontrol on it. Is this possible and in addition could you suggest a way to do it? How should the control be hosted?
class MyCustomPin : MapVisualElement
{
}
Regards,
Thomas
3 Answers, 1 is accepted
Thank you for writing.
User controls cannot be hosted in the MapPin object. Can you please share more details about your actual setup and we will suggest the best way to accomplish your task?
I hope this helps. Looking forward to your reply.
Regards,
Hristo
Progress Telerik
Hi Hristo,
A little more detail:
I'm receiving events from from different objects in near to real time. The objects are placed on the map and I would like to show different performance stats for each of the objects in a usercontrol on the map. I've attached a mockup of the control just to give you an idea.
I guess something like this could be done, but I dont know how it will perform... and it would be nicer just to update the UC each time a new evet is recieved...
MarkerDetailControl mdc = new MarkerDetailControl();
Bitmap b = new Bitmap(mdc.Width, mdc.Height);
mdc.DrawToBitmap(b, new Rectangle(0, 0, b.Width, b.Height));
//and then
MyCustomMarker.Image = b;
//Add to layer on so on...
Thank you for writing.
As I understand creating an image out of your user control and adding it to the chart would be suitable for your actual project. This can be accomplished by creating a custom pin element with an Image property. The logic for painting the actual image can be implemented in the Paint method override:
public
class
CustomMapPin : MapPin
{
private
Image image;
private
PointL pixelLocation;
private
RectangleL drawRect;
public
CustomMapPin(PointG location)
:
base
(location)
{
}
public
Image Image
{
get
{
return
image;
}
set
{
this
.image = value;
}
}
public
override
bool
IsInViewport
{
get
{
return
true
; }
}
public
override
void
Paint(IGraphics graphics, IMapViewport viewport)
{
if
(
this
.Image ==
null
)
{
base
.Paint(graphics, viewport);
return
;
}
object
state = graphics.SaveState();
graphics.TranslateTransform(drawRect.X, drawRect.Y);
Graphics g = graphics.UnderlayGraphics
as
Graphics;
long
mapSize = MapTileSystemHelper.MapSize(viewport.ZoomLevel);
for
(
int
i = -1; i <= viewport.NumberOfWraparounds; i++)
{
g.DrawImage(
this
.Image,
new
RectangleF(i * mapSize, 0,
this
.Image.Size.Width,
this
.Image.Size.Height));
}
graphics.RestoreState(state);
}
public
override
void
ViewportChanged(IMapViewport viewport, ViewportChangeAction action)
{
if
(
this
.Image ==
null
)
{
base
.ViewportChanged(viewport, action);
return
;
}
long
mapSize = MapTileSystemHelper.MapSize(viewport.ZoomLevel);
if
((action & ViewportChangeAction.Zoom) != 0)
{
this
.pixelLocation = MapTileSystemHelper.LatLongToPixelXY(
this
.Location, viewport.ZoomLevel);
}
if
((action & ViewportChangeAction.Pan) != 0)
{
this
.drawRect =
new
RectangleL(pixelLocation.X -
this
.Image.Size.Width / 2, pixelLocation.Y -
this
.Image.Size.Height,
this
.Image.Size.Width,
this
.Image.Size.Height);
}
}
public
override
bool
HitTest(PointG pointG, PointL pointL, IMapViewport viewport)
{
if
(
this
.Image ==
null
)
{
return
base
.HitTest(pointG, pointL, viewport);
}
return
this
.drawRect.Contains(pointL);
}
}
You can use the custom pins just as the base object it extends:
this
.radMap1.Layers.Add(
new
MapLayer(
"L1"
));
CustomMapPin marker =
new
CustomMapPin(
new
PointG(36, -110));
marker.Size =
new
Size(50, 50);
marker.Image = Properties.Resources.bell;
this
.radMap1.Layers[
"L1"
].Add(marker);
I hope this helps. Should you have further questions please do not hesitate to write back.
Regards,
Hristo
Progress Telerik