2

我正在尝试实现用户在 Bing Map 控件上绘制和细化多边形的能力。

我添加了一个形状图层,并覆盖了点击事件以绘制一个简单的多边形,这一切都完美无缺。我想进一步完善控件,以便用户可以拖放绘制多边形的任何 Location 对象以改变其形状,但我没有任何运气。

我试图添加一个 MapItemControl,绑定到我的多边形的 Locations 属性,但没有成功 - 我没有看到图钉出现在地图上,即使我的多边形渲染正确。大概 Locations 集合没有通知 UI 集合的任何更改,因此我可能必须为这些图钉维护一个单独的集合。

然而,一旦我开始这样做,我仍然需要能够拖放引脚来修改多边形。有没有人在 Windows 8 上实现了这个,可以分享一些想法,拜托?

编辑

现在,我的图钉在地图上显示了 Locations 集合。理想情况下,我希望将这些与多边形的 Locations 集合联系起来,但乞丐不能成为选择者。我现在只需要能够拖动别针。

4

1 回答 1

2

我向多边形添加了一个拖动手柄模块,以便编辑多边形中的每个点。这是我使用的演练。

拖动手柄模块

这是针对 7.0 版的。不确定您使用的是哪个版本,但它很容易适应。

编辑我在 javascript/html 中做了这个。刚刚注意到您将其标记为 windows 8。好奇,您是否正在为 windows 8 手机制作银光控件?

WPF C# 解决方案

这是我想出的,它很容易实现,你需要做的就是把我的事件挂到你的MapPolygon对象上。代码背后的想法是,一旦您单击多边形,我们就会在多边形的每个顶点放置一个图钉(我们创建事件以便我们可以拖动它)。当我们拖放每个图钉时,我们会根据需要调整多边形。位置。

polygon.MouseDown += new MouseButtonEventHandler(polygon_MouseDownResize);

还有一种退出调整大小事件的方法,我选择只按下键并使用“esc”停止编辑,但您可以通过右键单击或您选择的任何其他事件来执行此操作。您所做的只是清除pushPinVertices列表和重置事件变量。

// === Editable polygon Events ===

private bool _shapeEdit;
public MapPolygon selectedPoly { get; set; }
public List<Pushpin> pushPinVertices { get; set; }


void polygon_MouseDownResize(object sender, MouseButtonEventArgs e)
{

    if (!_shapeEdit && selectedPoly == null)
    {
        _shapeEdit = true;
        selectedPoly = sender as MapPolygon;
        pushPinVertices = new List<Pushpin>();
        int i = 0;
        foreach (Microsoft.Maps.MapControl.WPF.Location vertice in selectedPoly.Locations)
        {
            Pushpin verticeBlock = new Pushpin();
            // I use a template to place a 'vertice marker' instead of a pushpin, il provide resource below
            verticeBlock.Template = (ControlTemplate)Application.Current.Resources["PushPinTemplate"];
            verticeBlock.Content = "vertice";
            verticeBlock.Location = vertice;
            verticeBlock.MouseDown += new MouseButtonEventHandler(pin_MouseDown);
            verticeBlock.MouseUp += new MouseButtonEventHandler(pin_MouseUp);
            myMap.Children.Add(verticeBlock);
            pushPinVertices.Add(verticeBlock);
            i++;

        }
    }

}



private void myMap_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == System.Windows.Input.Key.Escape)
    {
        if (_shapeEdit && selectedPoly != null)
        {

            foreach (Pushpin p in pushPinVertices)
            {
                myMap.Children.Remove(p);
            }

            _shapeEdit = false;
            selectedPoly = null;

        }

    }
}
// Note: I needed my window to pass bing maps the keydown event
private void Window_KeyDown(object sender, KeyEventArgs e)
{
    myMap_KeyDown(sender, e);
}


// === Editable polygon Events ===

// ==== Draggable pushpin events =====
Vector _mouseToMarker;
private bool _IsPinDragging;
public Pushpin SelectedPushpin { get; set; }

void pin_MouseUp(object sender, MouseButtonEventArgs e)
{
    LocationCollection locCol = new LocationCollection();
    foreach (Pushpin p in pushPinVertices)
    {
        locCol.Add(p.Location);

    }

    selectedPoly.Locations = locCol;
    bingMapRefresh();

    _IsPinDragging = false;
    SelectedPushpin = null;
}

void pin_MouseDown(object sender, MouseButtonEventArgs e)
{
    e.Handled = true;
    SelectedPushpin = (Pushpin)sender;
    _IsPinDragging = true;
    _mouseToMarker = Point.Subtract(
        myMap.LocationToViewportPoint(SelectedPushpin.Location),
        e.GetPosition(myMap));

}

private void myMap_MouseMove(object sender, MouseEventArgs e)
{
    if (e.LeftButton == MouseButtonState.Pressed)
    {
        if (_IsPinDragging && SelectedPushpin != null)
        {
            SelectedPushpin.Location = myMap.ViewportPointToLocation(Point.Add(e.GetPosition(myMap), _mouseToMarker));
            e.Handled = true;
        }
    }
}
// ==== Draggable pushpin events =====
// Nice little maprefresh I found online since the bingmap WPF doesnt always seem to update elements after certain event orders
private void bingMapRefresh()
{
    //myMap.UpdateLayout();
    var mapCenter = myMap.Center;
    mapCenter.Latitude += 0.00001;
    myMap.SetView(mapCenter, myMap.ZoomLevel);
}

至于覆盖图钉图标的资源,我只是使用了ImageBrush一个制作了一个白色的小方块。请注意,您可能需要Margin根据标记的长度/宽度来调整属性。这是因为通常默认情况下图钉锚定在该位置上方。

<Application.Resources>
    <ControlTemplate x:Key="PushPinTemplate">
        <Grid>
            <Rectangle Width="10" Height="10" Margin="0 35 0 0">
                <Rectangle.Fill>
                    <ImageBrush ImageSource="pack://application:,,,/Images/DragIcon.gif"/>
                </Rectangle.Fill>
            </Rectangle>
        </Grid>
    </ControlTemplate>
</Application.Resources>
于 2012-10-02T19:34:23.583 回答