none
How to handle map control's pointer events? RRS feed

  • Question

  • I try to implement a draggable mapicon behaviour.

    As i see it can be done through pointer events (PointerPressed, PinterMoved, PointerReleased).

    But this events do not fire with a map control. PointerPressed event fires with controls added to the map control's children property and on right click when the attached flyout is shown.

    Can anybody help me with my issue?

    Monday, October 24, 2016 9:04 AM

Answers

  • A workaround i've found.

    1. Add a transparent Rectangle over a MapControl with pointer events' handlers

    <Rectangle x:Name="Rect"
                       HorizontalAlignment="Stretch" 
                       VerticalAlignment="Stretch" 
                       Fill="Transparent" 
                       Canvas.ZIndex="10" 
                       IsHitTestVisible="False"
                       PointerPressed="Rect_PointerPressed" 
                       PointerMoved="Rect_PointerMoved"
                       PointerReleased="Rect_PointerReleased"/>

    2. Add handler for MapControl's event as the same in rectangle (strange behaviour of a MapContol, but it does not work without it)

    MapControl.AddHandler(MapControl.PointerPressedEvent, new PointerEventHandler(Rect_PointerPressed), true);

    3. Set any "dragflag" (to detect drag operation) and Rect.IsHitTestVisible to true in the Rect_PointerPressed method, set a MapElement that should be dragged to variable

    public void Rect_PointerPressed(object sender, PointerRoutedEventArgs e)
            {
                e.Handled = false;
                var pointer = e.GetCurrentPoint(MapControl);
                if (pointer.Properties.IsLeftButtonPressed)
                {
                    var point = pointer.Position;
                    var mapElementsInPoint = MapControl.FindMapElementsAtOffset(point);
                    if (mapElementsInPoint.Count != 0)
                    {
                        _mapElementToDrag = mapElementsInPoint.First();//get element to drag - firts for example
                        _isMapDragging = true; //dragflag
                        Rect.IsHitTestVisible = true;
                        e.Handled = true;
                    }
                }
            }

    4. Handle drag operation in the Rect_PointerMoved method

    private void Rect_PointerMoved(object sender, PointerRoutedEventArgs e)
            {
                e.Handled = false;
                if(_isMapDragging)
                {
                    var dragPosition = e.GetCurrentPoint(MapControl).Position;//coordinates for pointer
                    //set dragPosition to your MapElement
                    //for example if it is a MapIcon
                    var mapIcon = (MapIcon)_mapElementToDrag;
                    mapIcon.Location = dragPosition;
                    e.Handled = true;
                }
            }

    5. Reset your "dragflag" and Rect.IsHitTestVisible to false in the Rect_PointerReleased method

    private void Rect_PointerReleased(object sender, PointerRoutedEventArgs e)
            {
                e.Handled = false;
                if(_isMapDragging)
                {
                    Rect.IsHitTestVisible = false;
                    _isMapDragging = false;
                    _mapElementToDrag = null;
                    e.Handled = true;
                }
            }

    You are done for now!


    Thursday, October 27, 2016 3:10 PM

All replies

  • The UWP map control currently doesn't raise the base pointer events. I don't know of a workaround for this.
    • Proposed as answer by Ricky_Brundritt Tuesday, October 25, 2016 5:19 PM
    • Unproposed as answer by AlexeySubbotin Thursday, October 27, 2016 3:10 PM
    Tuesday, October 25, 2016 4:47 PM
    Moderator
  • A workaround i've found.

    1. Add a transparent Rectangle over a MapControl with pointer events' handlers

    <Rectangle x:Name="Rect"
                       HorizontalAlignment="Stretch" 
                       VerticalAlignment="Stretch" 
                       Fill="Transparent" 
                       Canvas.ZIndex="10" 
                       IsHitTestVisible="False"
                       PointerPressed="Rect_PointerPressed" 
                       PointerMoved="Rect_PointerMoved"
                       PointerReleased="Rect_PointerReleased"/>

    2. Add handler for MapControl's event as the same in rectangle (strange behaviour of a MapContol, but it does not work without it)

    MapControl.AddHandler(MapControl.PointerPressedEvent, new PointerEventHandler(Rect_PointerPressed), true);

    3. Set any "dragflag" (to detect drag operation) and Rect.IsHitTestVisible to true in the Rect_PointerPressed method, set a MapElement that should be dragged to variable

    public void Rect_PointerPressed(object sender, PointerRoutedEventArgs e)
            {
                e.Handled = false;
                var pointer = e.GetCurrentPoint(MapControl);
                if (pointer.Properties.IsLeftButtonPressed)
                {
                    var point = pointer.Position;
                    var mapElementsInPoint = MapControl.FindMapElementsAtOffset(point);
                    if (mapElementsInPoint.Count != 0)
                    {
                        _mapElementToDrag = mapElementsInPoint.First();//get element to drag - firts for example
                        _isMapDragging = true; //dragflag
                        Rect.IsHitTestVisible = true;
                        e.Handled = true;
                    }
                }
            }

    4. Handle drag operation in the Rect_PointerMoved method

    private void Rect_PointerMoved(object sender, PointerRoutedEventArgs e)
            {
                e.Handled = false;
                if(_isMapDragging)
                {
                    var dragPosition = e.GetCurrentPoint(MapControl).Position;//coordinates for pointer
                    //set dragPosition to your MapElement
                    //for example if it is a MapIcon
                    var mapIcon = (MapIcon)_mapElementToDrag;
                    mapIcon.Location = dragPosition;
                    e.Handled = true;
                }
            }

    5. Reset your "dragflag" and Rect.IsHitTestVisible to false in the Rect_PointerReleased method

    private void Rect_PointerReleased(object sender, PointerRoutedEventArgs e)
            {
                e.Handled = false;
                if(_isMapDragging)
                {
                    Rect.IsHitTestVisible = false;
                    _isMapDragging = false;
                    _mapElementToDrag = null;
                    e.Handled = true;
                }
            }

    You are done for now!


    Thursday, October 27, 2016 3:10 PM