如何为可拖动的图钉设置动画

时间:2011-01-01 16:54:32

标签: silverlight bing-maps pushpin

我正在寻找一种方法来显示推针被拖动到地图上的动作。 我试图修改这里提出的一个例子: http://peteohanlon.wordpress.com/2010/10/10/draggable-pushpins/通过更新委托中的AssociatedObject.Location添加到MouseMove事件处理程序,但这没有结果。推针保持在它的位置,直到松开鼠标按钮的那一刻。然后它跳转到新位置。

任何想法如何强制MapLayer在拖动过程中跟踪推针位置并在鼠标移动时正确重绘?

3 个答案:

答案 0 :(得分:1)

马克斯,你能澄清一下你想做什么吗?你的方法听起来很合理,但是每次鼠标移动时,地图都会重新计算引脚的位置。这样的事情怎么样?:

  1. 当引脚进入拖动模式时,它将从地图中删除,并替换为仅存在于屏幕空间中的可拖动引脚。因此,用户在屏幕空间中拖动“图钉”,而不是地图空间。

  2. 当用户结束拖动时,您将屏幕位置转换为地图位置(位置对象),然后将其添加回地图。

答案 1 :(得分:0)

我在制定自己的解决方案时遇到了这个问题,我很高兴看到它完全像你描述的那样工作,我想我会发布它。需要注意的是,我也使用2Way MVVM Binding模式,它可以完美运行。你需要两件事:

1)这个扩展方法有助于在运行时找到引脚的父级MapLayer:

    public static T FindVisualParent<T>(this DependencyObject obj)
    where T : DependencyObject
    {
        DependencyObject parent = VisualTreeHelper.GetParent(obj);
        while (parent != null)
        {
            T typed = parent as T;
            if (typed != null)
            {
                return typed;
            }
            parent = VisualTreeHelper.GetParent(parent);
        }
        return null;
    }

2)在图钉上的Dragging事件处理程序中,调用该扩展方法以引用托管MapLayer,然后触发最美妙的InvalidateArrange方法(来自UIElement),如下所示:

    void ParentMap_MouseMove(object sender, MouseEventArgs e)
    {
        var map = sender as Microsoft.Maps.MapControl.Map;
        var parentLayer = this.FindVisualParent<MapLayer>();

        if (this.isDragging)
        {
            var mouseMapPosition = e.GetPosition(map);
            var mouseGeocode = map.ViewportPointToLocation(mouseMapPosition);
            this.Location = mouseGeocode;
            parentLayer.InvalidateArrange();
        }
    }

应该异步执行可视化更新,并在引脚拖动上为您提供良好的滑动行为。 HTH

答案 2 :(得分:0)

通过GestureListener在Silverlight Toolkit for WP7中有一个现成的解决方案:

<my:Pushpin Location="{Binding Location}">
<toolkit:GestureService.GestureListener>
  <toolkit:GestureListener DragDelta="GestureListener_DragDelta"  DragStarted="GestureListener_DragStarted"  DragCompleted="GestureListener_DragCompleted"/>
</toolkit:GestureService.GestureListener>
 </my:Pushpin>

private void GestureListener_DragStarted(object sender, DragStartedGestureEventArgs e)
{
Map.IsEnabled = false;
}

private void GestureListener_DragCompleted(object sender, DragCompletedGestureEventArgs e)
{
Map.IsEnabled = true;
}

private void GestureListener_DragDelta(object sender, DragDeltaGestureEventArgs e)
{
Point p = e.GetPosition(Map);
App.ViewModel.Location = Map.ViewportPointToLocation(p);
}