mvvm windows-phone-8 mvvm-light bing-maps pushpin

MVVM Windows Phone 8: agregar una colección de marcadores al mapa



windows-phone-8 mvvm-light (2)

Aquí está el código XAML:

<maps:Map x:Name="NearbyMap" Center="{Binding MapCenter, Mode=TwoWay}" ZoomLevel="{Binding ZoomLevel, Mode=TwoWay}" > <maptk:MapExtensions.Children> <maptk:MapItemsControl Name="StoresMapItemsControl" ItemsSource="{Binding Treks}"> <maptk:MapItemsControl.ItemTemplate> <DataTemplate> <maptk:Pushpin x:Name="RouteDirectionsPushPin" GeoCoordinate="{Binding Location}" Visibility="Visible" Content="test"/> </DataTemplate> </maptk:MapItemsControl.ItemTemplate> </maptk:MapItemsControl> <maptk:UserLocationMarker x:Name="UserLocationMarker" Visibility="Visible" GeoCoordinate="{Binding MyLocation}"/> </maptk:MapExtensions.Children> </maps:Map> 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"

PushPinModel tiene un atributo Location que es un GeoCoordinate. Treks es un ObservableCollection<PushPinModel> . Ejecuto este código y solo se muestra UserLocationMarker , que es mi ubicación actual.


El MapItemsControl aún no está enlazado a MVVM (lo que yo sé). Entonces, la mejor manera es establecer su ItemsSource en el código detrás de su vista.

¡Aún puedes usar la colección definida en tu ViewModel! Las opciones son:

  • a través de mensajes mvvm pasar a lo largo de la colección desde el modelo de vista al código detrás de la vista
  • utilice el contexto de datos de la vista para acceder a la colección, algo como esto: this.StoresMapItemsControl.ItemsSource = ServiceLocator.Current.GetInstance<MainViewModel>().Locations;

Finalmente lo hago funcionar mediante el uso de propiedad de dependencia. Agregué una nueva clase:

public static class MapPushPinDependency { public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.RegisterAttached( "ItemsSource", typeof(IEnumerable), typeof(MapPushPinDependency), new PropertyMetadata(OnPushPinPropertyChanged)); private static void OnPushPinPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { UIElement uie = (UIElement)d; var pushpin = MapExtensions.GetChildren((Map)uie).OfType<MapItemsControl>().FirstOrDefault(); pushpin.ItemsSource = (IEnumerable)e.NewValue; } #region Getters and Setters public static IEnumerable GetItemsSource(DependencyObject obj) { return (IEnumerable)obj.GetValue(ItemsSourceProperty); } public static void SetItemsSource(DependencyObject obj, IEnumerable value) { obj.SetValue(ItemsSourceProperty, value); } #endregion }

Y en el archivo .xaml que he agregado

xmlns:dp="clr-namespace:Treks.App.Util.DependencyProperties"

y ahora el archivo .xaml se ve así:

<maps:Map x:Name="NearbyMap" Center="{Binding MapCenter, Mode=TwoWay}" ZoomLevel="{Binding ZoomLevel, Mode=TwoWay}" dp:MapPushPinDependency.ItemsSource="{Binding Path=Treks}" > <maptk:MapExtensions.Children> <maptk:MapItemsControl Name="StoresMapItemsControl"> <maptk:MapItemsControl.ItemTemplate> <DataTemplate> <maptk:Pushpin x:Name="PushPins" GeoCoordinate="{Binding Location}" Visibility="Visible" Content="test"/> </DataTemplate> </maptk:MapItemsControl.ItemTemplate> </maptk:MapItemsControl> <maptk:UserLocationMarker x:Name="UserLocationMarker" Visibility="Visible" GeoCoordinate="{Binding MyLocation}"/> </maptk:MapExtensions.Children> </maps:Map>

Ahora todos los marcadores están correctamente renderizados.