Mouse Events Tutorial |
GeoBase provides classes and interfaces which allow objects rendered on an IMap to respond to mouse clicks.
In this tutorial we will create a new class called MouseablePushPin that extends the PushPin class supplied by GeoBase. As the PushPin class already knows how to render itself, all that we have to implement is mouse handling.
This interface must be implemented by objects that respond to mouse clicks. By defining the HitTest(Int32, Int32, IMap) method, an object is able to determine whether it lies beneath the co-ordinates of the mouse click. IMapMouseHandlers also have an associated MapMouseEventsHandler.
Tip |
---|
HitTest takes x, y parameters from a mouse event and performs some user-defined procedure to determine whether the coordinates lie within the area of the object. |
The following code is all that is necessary to create a MouseablePushPin class that fully implements IMapMouseHandler.
public class MouseablePushPin : Telogis.GeoBase.PushPin, Telogis.GeoBase.IMapMouseHandler { private int hoverOnIcon = Telogis.GeoBase.ImageUtils.Icons.PinVerticalRed; private int hoverOffIcon = Telogis.GeoBase.ImageUtils.Icons.PinVerticalBlack; // constructor public MouseablePushPin(LatLon locatedAt) : base(locatedAt) { this.Icon = hoverOffIcon; } // hit-testing public IMapMouseHandler HitTest(int x, int y, IMap map) { int x1, y1; map.LatLontoXY(out x1, out y1, this.Location); System.Drawing.Rectangle area; area = Telogis.GeoBase.ImageUtils.IconCache.Rectangle(this.Icon, x1, y1); if (area.Contains(x,y)) { return this; } else { return null; } } private MapMouseEventsHandler mme_handler = new MapMouseEventsHandler(); // gets the MapMouseEventsHandler - see below public MapMouseEventsHandler MapMouseEventsHandler { get { return mme_handler; } } // switch between hovered icons public void ToggleIcon() { if (this.Icon == hoverOnIcon) { this.Icon = hoverOffIcon; } else { this.Icon = hoverOnIcon; } } }
Note |
---|
In the HitTest method IconCache is used to determine the size and position of the PushPin icon on the map. This is necessary because the PushPin occupies an area of the screen larger than the coordinates at which it is anchored; thus the HitTest should check the whole area occupied by the icon. |
The purpose of the public MapMouseEventsHandler property is to allow event handlers to be attached directly to IMapMouseHandlers. Consider the following code fragment, which illustrates the attachment of event handlers.
... // mouse-up event private void mapCtrl_MouseUp(object sender, MouseEventArgs e) { LatLon location = mapCtrl.XYtoLatLon(e.X, e.Y); MouseablePushPin mpp = new MouseablePushPin(location); mpp.MapMouseEventsHandler.OnMouseEnter += new EventHandler(MapMouseEventsHandler_OnMouseEnter); mpp.MapMouseEventsHandler.OnMouseLeave += new EventHandler(MapMouseEventsHandler_OnMouseLeave); ((RendererList)mapCtrl.Renderer).Add(mpp); mapCtrl.Invalidate(); } // mouse-enter event private void MapMouseEventsHandler_OnMouseEnter(object sender, EventArgs e) { SenderObjects so = (SenderObjects) sender; MouseablePushPin mpp = (MouseablePushPin) so.Item; mpp.ToggleIcon(); mapCtrl.Invalidate(); } // mouse-leave event private void MapMouseEventsHandler_OnMouseLeave(object sender, EventArgs e) { SenderObjects so = (SenderObjects) sender; MouseablePushPin mpp = (MouseablePushPin) so.Item; mpp.ToggleIcon(); mapCtrl.Invalidate(); } ...
Note |
---|
sender is cast to a SenderObjects. This allows for retrieval of the object that generated the event, as well as the map upon which the event occurred. |