Как оживить перетаскиваемую канцелярскую кнопку - PullRequest
1 голос
/ 01 января 2011

Я ищу способ показать движение канцелярской кнопки, перетаскиваемой по карте. Я попытался изменить пример, предложенный здесь: http://peteohanlon.wordpress.com/2010/10/10/draggable-pushpins/ путем обновления AssociatedObject.Location в делегате, добавленном в обработчик событий MouseMove, но это не дает результатов. Канцелярская кнопка остается на своем месте до момента, когда кнопка мыши отпущена. Затем он переходит на новое место.

Есть идеи, как заставить MapLayer отслеживать местоположение канцелярской кнопки во время перетаскивания и правильно перерисовывать его при перемещении мыши?

Ответы [ 3 ]

1 голос
/ 01 января 2011

Макс, можете ли вы уточнить, что вы хотите сделать? Ваш подход здесь звучит разумно, но немного пересчитывать местоположение булавки при каждом перемещении мыши немного не нужно. А как насчет этого?

  1. Когда вывод переходит в режим перетаскивания, он удаляется с карты и заменяется перетаскиваемым выводом, который существует только в пространстве экрана. Таким образом, пользователь перетаскивает «булавку» в пространстве экрана, а не в пространстве карты.

  2. Когда пользователь заканчивает перетаскивание, вы преобразуете положение экрана в положение на карте (объект Location), а затем добавляете его обратно на карту.

0 голосов
/ 17 февраля 2012

Существует готовое к использованию решение в Silverlight Toolkit для WP7 через GestureListener:

<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);
}
0 голосов
/ 16 декабря 2011

Я сталкивался с этим, работая над своим собственным решением, и я был так счастлив видеть, что оно работает именно так, как вы описали, я решил опубликовать его. Отметим, что я также использую шаблон привязки 2Way MVVM, и он работает безупречно. Вам нужно 2 вещи:

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) В обработчике события «Перетаскивание» на канцелярской кнопке вызовите этот метод расширения для ссылки на хост 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();
        }
    }

Это должно асинхронно выполнить визуальное обновление и дать вам хорошее поведение при перемещении по булавке. НТН

...