我很难将图钉添加到以我喜欢的方式工作的地图中。
首先,我尝试添加MapItemsControl并绑定它。
<map:MapItemsControl ItemsSource="{Binding Path=Locations}">
<map:MapItemsControl.ItemTemplate>
<DataTemplate>
<controls:NumberedCircle Number="{Binding Path=Number}" map:MapControl.Location="{Binding Path=Point}"/>
</DataTemplate>
</map:MapItemsControl.ItemTemplate>
</map:MapItemsControl>
这很有效,但是当你平移地图时看起来非常糟糕;地图平移和图钉图标之间有一个非常明显的延迟,赶上它们应该是的位置。如果我足够快地来回平移地图,我可以从街道的一边到另一边做一个图钉跳。这只发生在列表中的一个项目上,因此它不像地图被淹没。
以下是效果视频:http://youtu.be/9FIvkOf71bg
接下来,我尝试将MapIcons添加到MapElements集合中。这是在一个行为中完成的,因为我使用的是MVVM,但总体思路是
var mapIcon = new MapIcon() { Location = pushpinDrawBehavior.Location};
mapControl.MapElements.Add(mapIcon);
这很有效。我平移地图,无论我有多快,MapIcon都会保留在应有的位置。根本没有迟滞行为。但是 - 当您放大和缩小时,MapIcon会出现并消失,如文档中所述:
无法保证显示MapIcon。它可能会隐藏起来 隐藏地图上的其他元素或标签。
我非常沮丧,因为我有两种方法可以将图钉添加到地图中,并且由于不同的原因,它们都会产生可怕的用户体验。所以,问题是:
1)我错过了什么吗?有没有办法让XAML元素不会延迟?有没有办法让MapIcons始终可见?
2)有没有办法创建一个像MapIcon一样的自定义类?它派生自MapElement,但我不知道如何完成图钉的实际渲染,或者如何定义图像,标题等的布局。如果我可以创建自己的MapIcon,我可能会禁用隐藏行为。
编辑:在诺基亚925上运行应用程序并且效果不太明显(上面的视频来自521)。似乎保持与地图同步的XAML叠加层是处理器密集型的,并且在较小的硬件上会更糟糕。
答案 0 :(得分:2)
我害怕告诉你,除了减少元素的数量或图钉的XAML代码的复杂性之外,你无法做到这一点。
MapIcon和MapElements之间的区别在于MapIcons是Bitmaps,它直接发送到地图控件并在那里渲染,而MapElements是XAML元素并由XAML线程渲染。导致延迟的原因是地图线程中的地图交互与应用程序的UI线程之间需要同步。
您可以尝试的是将图钉的XAML作为位图(请参阅RenderTargetBitmap)。渲染可能需要一些时间,但随后您可以将它们用于MapIcons。但是,几个月前我试过这个,发现无法一直显示MapIcons。
由于我正在开发一个我想拥有MapIcons的应用程序,它总是可见的,所以我们希望将来会对Map组件进行更改。地图中有很多错误,例如我也无法改变推针的锚点...... MS可以在这里改进很多。
编辑:要了解有关地图控件和MapIcons / MapElements / ...的更多信息,请查看this BUILD conference talk。
答案 1 :(得分:0)
这可能是一个很长的镜头(并不太漂亮),但尝试在UI线程上填充MapItemsControl
。
为图钉创建一个类:
public class PushpinData
{
public GeoCoordinate Location { get; set; }
public string Text { get; set; }
public SolidColorBrush DisplayBrush { get; set; }
}
使用MapControl
为图钉创建DataTemplate
:
xmlns:maps="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps"
xmlns:maptk="clr-namespace:Microsoft.Phone.Maps.Toolkit;assembly=Microsoft.Phone.Controls.Toolkit"
<maps:Map x:Name="mapControl" >
<maptk:MapExtensions.Children>
<maptk:MapItemsControl x:Name="PushpinLayer">
<maptk:MapItemsControl.ItemTemplate>
<DataTemplate>
<maptk:Pushpin GeoCoordinate="{Binding Location}"
Content="{Binding Text}"
Background="{Binding DisplayBrush}"/>
</DataTemplate>
</maptk:MapItemsControl.ItemTemplate>
</maptk:MapItemsControl>
</maptk:MapExtensions.Children>
</maps:Map>
在地图控件的视图和Loaded
事件中声明您的图钉列表,获取对MapItemsControl
的引用并指定其ItemsSource
:
using Microsoft.Phone.Maps.Toolkit;
ObservableCollection<PushpinData> pushpinList = new ObservableCollection<PushpinData>();
mapControl.Loaded += (s, e) =>
{
ObservableCollection<DependencyObject> children = MapExtensions.GetChildren(mapControl);
var pushPinLayer = children.FirstOrDefault(x => x.GetType() == typeof(MapItemsControl)) as MapItemsControl;
pushPinLayer.ItemsSource = pushpinList;
}
完成后,您可以填充pushpinList
。为了避免破坏MVVM,您当然可以通过Messenger
种类从VM接收图钉列表。另外,请确保您的图钉集合仅包含在任何给定时间显示的图钉集合。