2013-05-07 15 views
6

Ecco il codice XAML:MVVM Windows Phone 8 - l'aggiunta di un insieme di simboli a una mappa

<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 ha un attributo Location che è un GeoCoordinate. Trek è un ObservableCollection<PushPinModel>. Eseguo questo codice e viene visualizzato solo il UserLocationMarker, che è la mia posizione corrente.

risposta

16

Finalmente lo faccio funzionare usando la proprietà di dipendenza. Ho aggiunto una nuova classe:

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 
} 

E nel file XAML ho aggiunto

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

e ora il file XAML simile a questo:

<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> 

Ora tutti i simboli sono correttamente resi

+0

Questo risolto il mio problema, eccellente approccio – xximjasonxx

+0

Grazie Ha risolto il problema così – robertk

+0

potrebbe anche fornire il codice per le Page.xaml.cs - non so come posso legare l'elenco effettivo di elementi della mappa (ad esempio 'Tracks ') per' Map' o 'MapItemsControl' –

3

Attualmente lo MapItemsControl non è ancora compatibile con MVVM (cosa che so per certo). Quindi il modo migliore è impostarlo nel codice ItemsSource dietro alla tua vista.

È comunque possibile utilizzare la raccolta definita nel ViewModel! Le opzioni sono:

  • attraverso la messaggistica MVVM passare lungo la collezione dal ViewModel al codice dietro della vista
  • usare il DataContext della vista per accedere alla raccolta, qualcosa di simile: this.StoresMapItemsControl.ItemsSource = ServiceLocator.Current.GetInstance<MainViewModel>().Locations;