Partager via


Xamarin.Forms Épingles de carte

Le contrôle Xamarin.FormsMap permet aux localisations d’être marquées avec des objets Pin. Un Pin est un marqueur de carte qui ouvre une fenêtre d’informations en cas d’appui :

Capture d’écran d’une épingle de carte et de sa fenêtre d’informations, sur iOS et Android

Lorsqu’un objet Pin est ajouté à la collection Map.Pins, le repère est affiché sur la carte.

La classe Pin a les propriétés suivantes:

  • Address, de type string, qui représente généralement l’adresse de la localisation du repère. Toutefois, il peut s’agir de n’importe quel contenu string, pas seulement d’une adresse.
  • Label, de type string, qui représente généralement le titre du repère.
  • Position, de type Position, qui représente la latitude et la longitude du repère.
  • Type, de type PinType, qui représente le type de repère.

Les propriétés s’appuient sur des objets BindableProperty, ce qui signifie qu’un Pin peut être la cible de liaisons de données. Pour plus d’informations sur les objets Pin de liaison de données, consultez Afficher une collection de repères.

En outre, la classe Pin définit des événements MarkerClicked et InfoWindowClicked. L’événement MarkerClicked est déclenché en cas d’appui sur un repère, et l’événement InfoWindowClicked est déclenché en cas d’appui sur la fenêtre d’informations. L’objet PinClickedEventArgs qui accompagne ces deux événements a une propriété unique HideInfoWindow, de type bool.

Afficher un repère

Vous pouvez ajouter un Pin à un Map en XAML :

<ContentPage ...
             xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps">
     <maps:Map x:Name="map"
               IsShowingUser="True"
               MoveToLastRegionOnLayoutChange="False">
         <x:Arguments>
             <maps:MapSpan>
                 <x:Arguments>
                     <maps:Position>
                         <x:Arguments>
                             <x:Double>36.9628066</x:Double>
                             <x:Double>-122.0194722</x:Double>
                         </x:Arguments>
                     </maps:Position>
                     <x:Double>0.01</x:Double>
                     <x:Double>0.01</x:Double>
                 </x:Arguments>
             </maps:MapSpan>
         </x:Arguments>
         <maps:Map.Pins>
             <maps:Pin Label="Santa Cruz"
                       Address="The city with a boardwalk"
                       Type="Place">
                 <maps:Pin.Position>
                     <maps:Position>
                         <x:Arguments>
                             <x:Double>36.9628066</x:Double>
                             <x:Double>-122.0194722</x:Double>
                         </x:Arguments>
                     </maps:Position>
                 </maps:Pin.Position>
             </maps:Pin>
         </maps:Map.Pins>
     </maps:Map>
</ContentPage>

Ce code XAML crée un objet Map qui affiche la région spécifiée par l’objet MapSpan. L’objet MapSpan est centré sur la latitude et la longitude représentées par un objet Position, qui couvre 0,01 degré de latitude et de longitude. Un objet Pin est ajouté à la collection Map.Pins, et dessiné sur le Map à la localisation spécifiée par sa propriété Position. Pour plus d’informations sur le struct, consultez Position et distance de la Position carte. Pour plus d’informations sur le passage d’arguments en XAML à des objets qui manquent de constructeurs par défaut, consultez Passage d’arguments en XAML.

Le code C# équivalent est :

using Xamarin.Forms.Maps;
// ...
Map map = new Map
{
  // ...
};
Pin pin = new Pin
{
  Label = "Santa Cruz",
  Address = "The city with a boardwalk",
  Type = PinType.Place,
  Position = new Position(36.9628066, -122.0194722)
};
map.Pins.Add(pin);

Avertissement

L’échec de la définition de la Pin.Label propriété entraîne une ArgumentException levée lors de l’ajout de la Pin propriété à un Map.

Cet exemple de code entraîne l’affichage d’un seul repère sur une carte :

Capture d’écran d’une épingle de carte, sur iOS et Android

Interagir avec un repère

Par défaut, en cas d’appui sur un Pin, sa fenêtre d’informations s’affiche :

Capture d’écran d’une épingle de carte et de sa fenêtre d’informations, sur iOS et Android

Un appui ailleurs sur la carte provoque la fermeture de la fenêtre d’informations.

La classe Pin définit un événement MarkerClicked, qui est déclenché en cas d’appui sur un Pin. Il n’est pas nécessaire de gérer cet événement pour afficher la fenêtre d’informations. Au lieu de cela, cet événement doit être géré lorsqu’il est nécessaire d’être averti qu’un appui sur un repère spécifique a été effectué.

La classe Pin définit également un événement InfoWindowClicked déclenché en cas d’appui sur une fenêtre d’informations. Cet événement doit être géré lorsqu’il est nécessaire d’être averti qu’un appui sur une fenêtre d’informations spécifique a été effectué.

Le code suivant montre un exemple de gestion de ces événements :

using Xamarin.Forms.Maps;
// ...
Pin boardwalkPin = new Pin
{
    Position = new Position(36.9641949, -122.0177232),
    Label = "Boardwalk",
    Address = "Santa Cruz",
    Type = PinType.Place
};
boardwalkPin.MarkerClicked += async (s, args) =>
{
    args.HideInfoWindow = true;
    string pinName = ((Pin)s).Label;
    await DisplayAlert("Pin Clicked", $"{pinName} was clicked.", "Ok");
};

Pin wharfPin = new Pin
{
    Position = new Position(36.9571571, -122.0173544),
    Label = "Wharf",
    Address = "Santa Cruz",
    Type = PinType.Place
};
wharfPin.InfoWindowClicked += async (s, args) =>
{
    string pinName = ((Pin)s).Label;
    await DisplayAlert("Info Window Clicked", $"The info window was clicked for {pinName}.", "Ok");
};

L’objet PinClickedEventArgs qui accompagne ces deux événements a une propriété unique HideInfoWindow, de type bool. Lorsque cette propriété a la valeur true à l’intérieur d’un gestionnaire d’événements, la fenêtre d’informations est masquée.

Types de repères

Les objets Pin incluent une propriété Type, de type PinType, qui représente le type de repère. L’énumération PinType définit les membres suivants :

  • Generic représente un repère générique.
  • Place représente un repère pour une localisation.
  • SavedPin représente un repère pour une localisation enregistrée.
  • SearchResult représente un repère pour un résultat de recherche.

Toutefois, la définition de la propriété Pin.Type sur n’importe quel membre PinType ne change pas l’apparence du repère affiché. Au lieu de cela, vous devez créer un renderer personnalisé pour personnaliser l’apparence des broches. Pour plus d’informations, consultez Personnalisation d’une épingle de carte.

Afficher une collection d’épingles

La classe Map définit les propriétés suivantes :

Important

La propriété ItemTemplate est prioritaire lorsque les propriétés ItemTemplate et ItemTemplateSelector sont toutes deux définies.

Vous pouvez remplir un Map avec des repères en utilisant une liaison de données pour lier sa propriété ItemsSource à une collection IEnumerable :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"
             x:Class="WorkingWithMaps.PinItemsSourcePage">
    <Grid>
        ...
        <maps:Map x:Name="map"
                  ItemsSource="{Binding Locations}">
            <maps:Map.ItemTemplate>
                <DataTemplate>
                    <maps:Pin Position="{Binding Position}"
                              Address="{Binding Address}"
                              Label="{Binding Description}" />
                </DataTemplate>
            </maps:Map.ItemTemplate>
        </maps:Map>
        ...
    </Grid>
</ContentPage>

Les données de la propriété ItemsSource sont liées à la propriété Locations du viewmodel connecté, qui retourne un ObservableCollection d’objets Location, qui est un type personnalisé. Chaque objet Location définit des propriétés Address et Description, de type string, et une propriété Position, de type Position.

L’apparence de chaque élément de la collection IEnumerable est définie en définissant la propriété ItemTemplate sur un DataTemplate qui contient un objet Pin qui établit une liaison de données à des propriétés appropriées.

Les captures d’écran suivantes montrent un Map affichage d’une Pin collection à l’aide de la liaison de données :

Capture d’écran de la carte avec des broches liées aux données, sur iOS et Android

Choisir l’apparence de l’élément au moment de l’exécution

Vous pouvez choisir l’apparence de chaque élément de la collection IEnumerable au moment de l’exécution, en fonction de la valeur de l’élément, en définissant la propriété ItemTemplateSelector sur un DataTemplateSelector :

<ContentPage ...
             xmlns:local="clr-namespace:WorkingWithMaps"
             xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps">
    <ContentPage.Resources>
        <local:MapItemTemplateSelector x:Key="MapItemTemplateSelector">
            <local:MapItemTemplateSelector.DefaultTemplate>
                <DataTemplate>
                    <maps:Pin Position="{Binding Position}"
                              Address="{Binding Address}"
                              Label="{Binding Description}" />
                </DataTemplate>
            </local:MapItemTemplateSelector.DefaultTemplate>
            <local:MapItemTemplateSelector.XamarinTemplate>
                <DataTemplate>
                    <!-- Change the property values, or the properties that are bound to. -->
                    <maps:Pin Position="{Binding Position}"
                              Address="{Binding Address}"
                              Label="Xamarin!" />
                </DataTemplate>
            </local:MapItemTemplateSelector.XamarinTemplate>    
        </local:MapItemTemplateSelector>
    </ContentPage.Resources>

    <Grid>
        ...
        <maps:Map x:Name="map"
                  ItemsSource="{Binding Locations}"
                  ItemTemplateSelector="{StaticResource MapItemTemplateSelector}" />
        ...
    </Grid>
</ContentPage>

L’exemple suivant présente la classe MapItemTemplateSelector :

public class MapItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate DefaultTemplate { get; set; }
    public DataTemplate XamarinTemplate { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        return ((Location)item).Address.Contains("San Francisco") ? XamarinTemplate : DefaultTemplate;
    }
}

La classe MapItemTemplateSelector définit les propriétés DefaultTemplate et XamarinTemplate DataTemplate, qui sont configurées sur différents modèles de données. La méthode OnSelectTemplate retourne le XamarinTemplate, qui affiche « Xamarin » en guise d’étiquette en cas d’appui sur un Pin, lorsque l’élément a une adresse qui contient « San Francisco ». Lorsque l’élément n’a pas d’adresse qui contient « San Francisco », la méthode OnSelectTemplate retourne le DefaultTemplate.

Remarque

Un cas d’usage pour cette fonctionnalité est la liaison de propriétés d’objets sous-classés Pin à différentes propriétés, en fonction du Pin sous-type.

Pour plus d’informations sur les sélecteurs de modèles de données, consultez Création d’un Xamarin.Forms DataTemplateSelector.