MouseDown on marker

Topics: Help
Jan 10, 2012 at 2:17 PM

There is not a built in event for mousedown on a marker.

Therefore I want to use the map's mousedown event and check to see if the mouse happens to be over a marker.  Is there a simple way to do this?

Jan 10, 2012 at 2:23 PM

MainMap.OnMarkerEnter
MainMap.OnMarkerLeave

save/reset current marker in these events

Jan 10, 2012 at 2:32 PM

I'm trying to move markers.  Unless I use a rectangle marker as you do in your example, I cannot use the OnMarkerLeave event to set my currentMarker to null.  If I do that, then the user cannot move the marker properly because as soon as the mouse moves off the marker, the marker is de-selected.

 

private void MainMap_OnMarkerEnter(GMapMarker item)
{
    currentMarker = item;
}

private void MainMap_MouseUp(object sender, MouseEventArgs e)
{
    isDraggingMarker = false;
    currentMarker = null;
}

private void MainMap_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        if (currentMarker != null)
            isDraggingMarker = true;
    }
}

private void MainMap_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left && isDraggingMarker && currentMarker != null)
    {
        currentMarker.Position = MainMap.FromLocalToLatLng(e.X, e.Y);
        MainMap.Refresh();
    }
}

The above code works great when the user does what is intended: IE they mouse over a marker, mousedown on it and drag.  The problem is that if they simply mouseover a marker and then click down somewhere else on the map, the marker moves because I am not catching that the marker is no longer the currentMarker.

I really want to avoid doing what you did with the rectangular marker for moving markers.  I have too many on the map and it gets congested quickly.

Thoughts?

Jan 10, 2012 at 2:35 PM

Maybe I could do what you do but make the rectangular marker borderless (totally transparent).  I'd prefer to find a better solution though.

Jan 10, 2012 at 2:44 PM

I'm assuming that in my MouseDown listener I need to sweep through all the markers of each overlay and check to see if the LocalArea property contains the mouse position.  If so, then I can declare that I'm dragging a marker.

private void MainMap_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        for (int i = Overlays.Count - 1; i >= 0; i--)
        {
            GMapOverlay o = Overlays[i];
            if (o != null && o.IsVisibile)
                foreach (GMapMarker m in o.Markers)
                    if (m.IsVisible && m.IsHitTestVisible && m.LocalArea.Contains(e.X, e.Y))
                    {
                        currentMarker = m;
                        isDraggingMarker = true;
                    }
        }
    }
}
Jan 10, 2012 at 2:54 PM

try this instead:

private void MainMap_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
 if (currentMarker != null && currentMarker.IsMouseOver)
 {
  isDraggingMarker = true;
  }
}
}

then if you click down not in markers area it will not move

Jan 10, 2012 at 2:56 PM

This worked great.  For anyone interested, below is the final code I used.  This allows the user to move markers without using a rectangular marker around it to capture the movement. 

In my example, I specify which overlays I want to check the markers for.  i do this because I move moveable markers are some overlays and fixed markers on others.  No need to check an overlay with nothing but fixed markers.

Radioman: Any chance of you adding a built-in MarkerMouseDown event?

 

private void MainMap_MouseUp(object sender, MouseEventArgs e)
{
    isDraggingMarker = false;
    currentMarker = null;
}

private void MainMap_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        GMapOverlay[] overlays = new GMapOverlay[] { polygons, top };
        for (int i = overlays.Length - 1; i >= 0; i--)
        {
            GMapOverlay o = overlays[i];
            if (o != null && o.IsVisibile)
                foreach (GMapMarker m in o.Markers)
                    if (m.IsVisible && m.IsHitTestVisible && m.LocalArea.Contains(e.X, e.Y))
                    {
                        currentMarker = m;
                        isDraggingMarker = true;
                        return;
                    }
        }
    }
}

private void MainMap_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left && isDraggingMarker && currentMarker != null)
    {
        currentMarker.Position = MainMap.FromLocalToLatLng(e.X, e.Y);
        MainMap.Refresh();
    }
}
Jan 10, 2012 at 3:05 PM

Oh okay.  Didn't know that property existed.  I just tested it and it worked great.  I just made one additional change in my OnMarkerEnter listener.  I check to see if we are currently dragging a marker.  This prevents the focus from switching from the marker you are currently dragging to the new marker you just passed over/behind. 

Thanks for all the help radioman.

private void MainMap_OnMarkerEnter(GMapMarker item)
{
    if (!isDraggingMarker)
        currentMarker = item;
}

private void MainMap_MouseUp(object sender, MouseEventArgs e)
{
    isDraggingMarker = false;
    currentMarker = null;
}

private void MainMap_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
        if (currentMarker != null && currentMarker.IsMouseOver)
            isDraggingMarker = true;
}

private void MainMap_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left && isDraggingMarker && currentMarker != null)
    {
        currentMarker.Position = MainMap.FromLocalToLatLng(e.X, e.Y);
        MainMap.Refresh();
    }
}
Jan 10, 2012 at 3:07 PM

p.s. manually checking m.LocalArea.Contains(e.X, e.Y)) doesn't work correctly in the last changesets, you can check if overlay is correct in OnMarkerEnter event

Jan 10, 2012 at 3:52 PM

Yep that is what I'm doing.  I stripped my code before posting.  Thanks for the heads up about LocalArea.Contains().