Xamarin.Forms Karten-Pins
Mit dem Xamarin.FormsMap
-Steuerelement können Speicherorte mit Pin
-Objekten markiert werden. Ein Pin
ist eine Kartenmarkierung, die beim Antippen ein Informationsfenster öffnet:
Wenn ein Pin
-Objekt zur Map.Pins
-Sammlung hinzugefügt wird, wird die Stecknadel auf der Karte gerendert.
Die Pin
-Klasse weist die folgenden Eigenschaften auf:
Address
, vom Typstring
, der in der Regel die Adresse für den Pinspeicherort darstellt. Es kann jedoch jederstring
Inhalt sein, nicht nur eine Adresse.Label
, vom Typstring
, der in der Regel den Pintitel darstellt.Position
, vom TypPosition
, der den Breiten- und Längengrad des Pins darstellt.Type
, vom TypPinType
, der den Typ des Pins darstellt.
Diese Eigenschaften werden durch BindableProperty
-Objekte unterstützt, was bedeutet, dass ein Pin
das Ziel von Datenbindungen sein kann. Weitere Informationen zur Datenbindung Pin
von Objekten finden Sie unter Anzeigen einer Pinsammlung.
Darüber hinaus definiert die Klasse Pin
die Ereignisse MarkerClicked
und InfoWindowClicked
. Das MarkerClicked
-Ereignis wird ausgelöst, wenn auf eine Pin getippt wird und das InfoWindowClicked
-Ereignis ausgelöst wird, wenn auf das Informationsfenster getippt wird. Das PinClickedEventArgs
-Objekt, das die beiden Ereignisse begleitet, hat eine einzige HideInfoWindow
-Eigenschaft vom Typ bool
.
Anzeigen einer Pin
Ein Pin
kann zu einem Map
in XAML hinzugefügt werden:
<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>
Erstellt ein neues Map
-Objekt, das die von MapSpan
angegebene Region anzeigt. Das MapSpan
-Objekt wird auf dem Breiten- und Längengrad zentriert, das durch ein Position
-Objekt dargestellt wird, das 0,01 Breiten- und Längengrad erweitert. Ein Pin
-Objekt wird der Map.Pins
-Sammlung hinzugefügt und auf dem Map
an der durch seine Position
-Eigenschaft angegebenen Stelle gezeichnet. Informationen zur Position
Struktur finden Sie unter Kartenposition und Abstand. Informationen zum Übergeben von Argumenten in XAML an Objekte ohne Standardkonstruktoren finden Sie unter Übergeben von Argumenten in XAML.
Der entsprechende C#-Code lautet:
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);
Warnung
Fehler beim Festlegen der Pin.Label
Eigenschaft führt dazu, dass die ArgumentException
Eigenschaft ausgelöst wird, wenn die Eigenschaft Pin
einem Map
hinzugefügt wird.
Dieser Beispielcode führt dazu, dass ein einzelner Pin auf einer Karte gerendert wird:
Interagieren mit Fragen und Antworten
Wenn auf ein Pin
-Informationsfenster getippt wird, wird standardmäßig folgendes angezeigt:
Durch Tippen an einer anderen Stelle auf der Karte wird das Informationsfenster geschlossen.
Die Pin
-Klasse definiert ein MarkerClicked
-Ereignis, das ausgelöst wird, wenn ein Pin
angetippt wird. Es ist nicht erforderlich, dieses Ereignis zu behandeln, um das Informationsfenster anzuzeigen. Stattdessen sollte dieses Ereignis behandelt werden, wenn eine Anforderung besteht, benachrichtigt zu werden, dass eine bestimmte Pin angetippt wurde.
Die Pin
-Klasse definiert auch ein InfoWindowClicked
-Ereignis, das ausgelöst wird, wenn auf ein Informationsfenster getippt wird. Dieses Ereignis sollte behandelt werden, wenn eine Anforderung besteht, benachrichtigt zu werden, dass auf ein bestimmtes Informationsfenster getippt wurde.
Der folgende Code zeigt ein Beispiel für die Behandlung dieser Ereignisse:
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");
};
Das PinClickedEventArgs
-Objekt, das die beiden Ereignisse begleitet, hat eine einzige HideInfoWindow
-Eigenschaft vom Typ bool
. Wenn diese Eigenschaft innerhalb eines Event-Handlers auf true
gesetzt wird, wird das Informationsfenster ausgeblendet.
Pintypen
Pin
-Objekte enthalten eine Type
-Eigenschaft vom Typ PinType
, die den Typ des Pins darstellt. Die PinType
-Enumeration definiert die folgenden Members:
Generic
, stellt einen generischen Benutzer dar.Place
, stellt einen Pin für eine Stelle dar.SavedPin
, stellt einen Pin für einen gespeicherten Speicherort dar.SearchResult
, stellt einen Pin für ein Suchergebnis dar.
Das Festlegen der Pin.Type
-Eigenschaft auf ein PinType
-Element ändert jedoch nicht die Darstellung der gerenderten Pin. Stattdessen müssen Sie einen benutzerdefinierten Renderer erstellen, um die Pindarstellung anzupassen. Weitere Informationen finden Sie unter Anpassen eines Kartennadels.
Anzeigen einer PIN-Sammlung
Die Map
-Klasse definiert die folgenden Eigenschaften:
ItemsSource
, vom TypIEnumerable
, der die Auflistung derIEnumerable
anzuzeigenden Elemente angibt.ItemTemplate
, vom TypDataTemplate
, der angibt, dass aufDataTemplate
jedes Element in der Auflistung der angezeigten Elemente angewendet werden soll.ItemTemplateSelector
, vom TypDataTemplateSelector
, der angibtDataTemplateSelector
, dass zum Auswählen einesDataTemplate
Elements zur Laufzeit verwendet wird.
Wichtig
Die Eigenschaft ItemTemplate
hat Vorrang, wenn sowohl die Eigenschaften ItemTemplate
als auch ItemTemplateSelector
festgelegt sind.
Ein Map
kann mit Pins bestückt werden, indem seine ItemsSource
-Eigenschaft mittels Datenbindung an eine IEnumerable
-Sammlung gebunden wird:
<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>
Die ItemsSource
-Eigenschaftsdaten sind an die Locations
-Eigenschaft des verbundenen Viewmodels gebunden, das ein ObservableCollection
-Objekt von Location
zurückgibt, das ein benutzerdefinierter Typ ist. Jedes Location
-Objekt definiert Address
- und Description
-Eigenschaften vom Typ string
und eine Position
-Eigenschaft vom Typ Position
.
Das Aussehen jedes Elements in der IEnumerable
-Sammlung wird definiert, indem die ItemTemplate
-Eigenschaft auf ein DataTemplate
gesetzt wird, das ein Pin
-Objekt enthält, das mit den entsprechenden Eigenschaften verknüpft ist.
Die folgenden Screenshots zeigen eine Map
Pin
Sammlung mit Datenbindung:
Auswählen der Elementdarstellung zur Laufzeit
Das Aussehen jedes Elements in der IEnumerable
-Sammlung kann zur Laufzeit auf der Grundlage des Elementwerts ausgewählt werden, indem die ItemTemplateSelector
-Eigenschaft auf ein DataTemplateSelector
gesetzt wird:
<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>
Im folgenden Beispiel wird die MapItemTemplateSelector
-Klasse gezeigt.
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;
}
}
Die Klasse MapItemTemplateSelector
definiert DefaultTemplate
- und XamarinTemplate
DataTemplate
-Eigenschaften, die auf verschiedene Datenvorlagen festgelegt sind. Die OnSelectTemplate
-Methode gibt das XamarinTemplate
zurück, das „Xamarin“ als Beschriftung anzeigt, wenn ein Pin
angetippt wird und das Element eine Adresse hat, die „San Francisco“ enthält. Wenn das Objekt keine Adresse hat, die „San Francisco“ enthält, gibt die Methode OnSelectTemplate
den Wert DefaultTemplate
zurück.
Hinweis
Ein Appsfall für diese Funktionalität ist die Bindung von Eigenschaften von Pin
-Objekten der Unterklassen an verschiedene Eigenschaften, basierend auf dem Pin
-Subtyp.
Weitere Informationen zu Datenvorlagenselektoren finden Sie unter Creating a Xamarin.Forms DataTemplateSelector.