Making Pushpin Locations Immoveable
Fernando Velasquez shares a solution for preventing a user from moving pushpins on a map
Recently, I came up against the problem of preventing a user from dragging around the map
certain pushpins created programmatically. The idea behind this is that it is sometimes useful t
o prevent the pushpins from being moved because afterwards the user may not remember where
the pushpin was originally and the whole idea of representing information in a map loses its value.
What gave me a clue about how it could be done easily is the way in which one carries out the
action of moving a pushpin around the map. The dragging action of a pushpin differs slightly from
the dragging action we can carry out for a desktop icon, in which you only need to click on it
and start dragging. In MapPoint, this is a two-step process. First, you need to click on the pushpin
for it to be selected, and then you need to click and hold on it to start dragging it around.
So, armed with this knowledge, I started out seeking a way to interrupt this process.
The solution I found involves doing some actions on the map in the middle of the dragging
process. By middle I mean the interval between the mouse click that selected the pushpin and
the mouse click that will start the dragging operation. Since I have found it impossible to move
a pushpin by making the mouse clicks real quick, meaning there is a short time span that has to
pass before being able to drag the pushpin, this gave me the idea that I could do a lot of things
in that interval.
The main purpose of doing some actions in the interval mentioned above is to have a way to
make it impossible for the user to accomplish the drag by just click and holding the selected
pushpin, so the easiest way to do this is just selecting another object just as soon as the
pushpin we donít want moved is selected. MapPoint exposes an event called SelectionChange,
which the help documentation states "Occurs when a selection on the map changes." This is the
event that will do the magic for us.
In simple terms, what the code below does is detect when the pushpin we donít want moved is
selected, create another selectable object in a location that will not be easily seen by the
user, select this new object and then delete it from the map, thus effectively shifting the
current selection from the pushpin and preventing the user from dragging it around.
Line 5 checks to see if the new selection made is of type MapPoint.Pushpin; if you are looking
to restrict a specific pushpin then more processing will need to be done, but for now Iíll focus
on restricting movement to anything that is a pushpin on the map. If the selection is a pushpin,
then a location object will be created. What is special about this location object is the place
it is being created: Latitude 80, Longitude 0 represents a place very far away, it is located
somewhere in the Arctic Ocean. You can actually choose any location you want, but the important
thing to keep in mind is that it should be a place where it is not near any of the locations you
are currently working with. Weíll see why next.
Lines 7-9 create a rectangle shape in the map, with its center located in the Arctic Ocean,
and with a width and height of 1. It is important that the rectangle is of small size so the
user wonít be able to notice the "magic" we are doing to keep the pushpins locked, and in the
case that we donít pay attention to the shapeís size, then the fact that it will be drawn far
away from where the user is looking at will also help to achieve the desired effect. Personally,
I think a combination of a far away object with a small size is the best one because there may
be cases where the user could be looking at the whole globe, so this would minimize any traces
of what has been done.
And thatís it! Now the user as much as he/she tries wonít be able to move anything that is
a pushpin around the map, unless through the event handler we give permission to do so.
A final note: there are two VERY important remarks in the documentation for the SelectionChange
event. One states that you shouldnít create any modal dialog boxes or message boxes inside
this event; since we donít do that in the code then thatís not a problem, but the next
one is. It says that we should NOT make that event infinitely recursive, either by calling
itself or causing itself to be called. This is the main reason a shape object and the if
statement in line 5 were used. Because the shape object is being programmatically selected,
this could result in the SelectionChange event being raised, naturally creating a recursive
call of itself, but since we first check to see if the newly selected object is a pushpin
before doing anything, then the call will not advance and the normal flow will be returned
when the code comes back from the recursion.
The above code was written to work under VB.Net, so I've included the code for VB6 here as well:
The logic is the same and the changes in code are minimal.
Discuss this story in the forum.
Author: Fernando Velasquez
Fernando works as a project manager for Real Systems, Inc. and also develops
VB.Net-based applications using MapPoint. He lives in Tegucigalpa, Honduras
(14.09489N, 87.20755W) and he enjoys sleeping, eating, reading books and solving
complex computational problems using genetic programming.