我正在尝试使用MVVM代码结构在Windows Phone 8上运行地图覆盖。我似乎无法使MapOverlay的GeoCoordinate属性正确绑定到我的ViewModel,我无法理解为什么。
XAML的立场是:
部首:
xmlns:maps="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps"
代码:
<maps:Map x:Name="Map" ZoomLevel="6" Height="500" Width="500" CartographicMode="Terrain" Center="{Binding MapCenter, Converter={StaticResource GpsCoordinateConverter}, Mode=TwoWay}">
<maps:Map.Layers>
<maps:MapLayer>
<maps:MapOverlay PositionOrigin="1,1" GeoCoordinate="{Binding MapCenter, Converter={StaticResource GpsCoordinateConverter}, Mode=OneWay}">
<Ellipse Fill="Blue" Height="20" Width="20" Opacity="50" />
</maps:MapOverlay>
</maps:MapLayer>
</maps:Map.Layers>
</maps:Map>
GpsCoordinateConverter
只是一个非常简单的类,它将我的视图模型中的数据类型更改为地图控件所期望的System.Device.Location.GeoCoordinate
。地图绑定的中心工作正常,但叠加层上的GeoCoordinate不会绑定,蓝色圆圈就位于地图的左上角。
我已经验证了PropertyChanged事件正在为我的模型触发,无论是通过调试还是因为地图中心本身正在更新,甚至尝试传递null来触发所有字段都无济于事。
我已经检查过调试,MapOverlay GeoCoordinate的属性似乎总是为空。我已经尝试将以下内容添加到代码隐藏中,将圆圈放在我想要的位置,但我似乎无法根据事件让它发生...
GpsCoordinateConverter converter = new GpsCoordinateConverter();
Map.Layers[0][0].GeoCoordinate = (GeoCoordinate)converter.Convert(((ViewModel.ReportViewModel)DataContext).MapCenter, typeof(GeoCoordinate), null, null);
有谁知道为什么会这样或如何解决这个问题?我不想放弃MVVM架构。
答案 0 :(得分:4)
这是Silverlight XAML Parser的限制。作为XAML元素属性的一部分初始化的对象将不参与同一逻辑树,因此没有将datacontext深入到它们中。
为了对新的诺基亚地图控件进行数据绑定,请使用新Windows Phone Toolkit中的MapExtensions。例如,这里使用MapExtensions how to create a PushPin in a specific GeoCoordinate。
<maps:Map x:Name="Map" Grid.Row="1" Hold="OnMapHold">
<maptk:MapExtensions.Children>
<maptk:Pushpin x:Name="RouteDirectionsPushPin" Visibility="Collapsed"/>
<maptk:MapItemsControl Name="StoresMapItemsControl">
<maptk:MapItemsControl.ItemTemplate>
<DataTemplate>
<maptk:Pushpin GeoCoordinate="{Binding GeoCoordinate}" Visibility="{Binding Visibility}" Content="{Binding Address}"/>
</DataTemplate>
</maptk:MapItemsControl.ItemTemplate>
</maptk:MapItemsControl>
<maptk:UserLocationMarker x:Name="UserLocationMarker" Visibility="Collapsed"/>
</maptk:MapExtensions.Children>
</maps:Map>
答案 1 :(得分:2)
要解决此问题,您需要隐式告诉绑定在何处找到该属性,在MVVM Light世界中它看起来像:
<maps:MapOverlay GeoCoordinate="{Binding Main.CurrentLocation, Source={StaticResource Locator}}">
<Ellipse Fill="Blue" Height="20" Width="20" Opacity="50" />
</maps:MapOverlay>
另外,您需要viewmodel上的调度程序来处理ui更改