Xamarin.Forms Закрепление карты
Элемент Xamarin.FormsMap
управления позволяет помечать расположения объектами Pin
. Маркер Pin
карты, который открывает окно сведений при нажатии:
Pin
При добавлении Map.Pins
объекта в коллекцию пин-код отображается на карте.
Класс Pin
имеет следующие свойства:
Address
string
Тип , который обычно представляет адрес для расположения пин-кода. Однако это может быть любоеstring
содержимое, а не только адрес.Label
типаstring
, который обычно представляет заголовок пин-кода.Position
Position
тип, представляющий широту и долготу закрепления.Type
тип, представляющий типPinType
пин-кода.
Эти свойства поддерживаются BindableProperty
объектами, что означает Pin
, что это может быть целевым объектом привязок данных. Дополнительные сведения о объектах привязки Pin
данных см. в разделе "Отображение коллекции закреплений".
Кроме того, Pin
класс определяет MarkerClicked
и InfoWindowClicked
события. Событие MarkerClicked
запускается при нажатии пин-кода, и InfoWindowClicked
событие запускается при нажатии окна сведений. Объект PinClickedEventArgs
, сопровождающий оба события, имеет одно HideInfoWindow
свойство типа bool
.
Отображение пин-кода
В XAML можно добавить следующее Pin
Map
:
<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>
Этот XAML создает объект, показывающий Map
регион, заданный MapSpan
объектом. Объект MapSpan
сосредоточен на широте и долготе, представленной Position
объектом, который расширяет 0,01 широты и долготы градусов. Объект Pin
добавляется в Map.Pins
коллекцию и рисуется Map
в расположении, указанном его Position
свойством. Сведения о структуре см. в Position
разделе "Положение карты" и "Расстояние". Сведения о передаче аргументов в XAML в объекты, которые не имеют конструкторов по умолчанию, см. в разделе "Передача аргументов в XAML".
Эквивалентный код на C# выглядит так:
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);
Предупреждение
Pin.Label
При добавлении свойства в свойство Map
возникает ArgumentException
ошибкаPin
.
Этот пример кода приводит к отрисовке одного пин-кода на карте:
Взаимодействие с закреплением
По умолчанию отображается окно сведений:Pin
Касание в другом месте карты закрывает окно сведений.
Класс Pin
определяет MarkerClicked
событие, которое запускается при Pin
нажатии. Для отображения окна сведений не требуется обрабатывать это событие. Вместо этого это событие должно обрабатываться, когда требуется уведомить о том, что определенный пин-код был нажат.
Класс Pin
также определяет InfoWindowClicked
событие, которое запускается при нажатии окна информации. Это событие должно обрабатываться, когда требуется уведомить о том, что определенное окно сведений было остановлено.
В следующем коде показан пример обработки этих событий:
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");
};
Объект PinClickedEventArgs
, сопровождающий оба события, имеет одно HideInfoWindow
свойство типа bool
. Если это свойство установлено true
внутри обработчика событий, окно сведений будет скрыто.
Типы закреплений
Pin
объекты включают Type
свойство типа PinType
, представляющее тип пин-кода. Перечисление PinType
определяет следующие члены:
Generic
представляет универсальный пин-код.Place
, представляет пин-код для места.SavedPin
, представляет пин-код для сохраненного расположения.SearchResult
— представляет пин-код для результата поиска.
Однако установка Pin.Type
свойства любому PinType
члену не изменяет внешний вид отрисованного закрепления. Вместо этого необходимо создать пользовательский отрисовщик для настройки внешнего вида пин-кода. Дополнительные сведения см. в разделе "Настройка пин-кода карты".
Отображение коллекции закрепленных элементов
Класс Map
определяет следующие свойства:
ItemsSource
типIEnumerable
, который указывает коллекцию отображаемыхIEnumerable
элементов.ItemTemplate
ТипDataTemplate
, который указываетDataTemplate
, что применяется к каждому элементу в коллекции отображаемых элементов.ItemTemplateSelector
типDataTemplateSelector
, который указываетDataTemplateSelector
, что будет использоваться для выбораDataTemplate
элемента во время выполнения.
Внимание
Свойство ItemTemplate
имеет приоритет, если заданы оба ItemTemplate
ItemTemplateSelector
свойства.
Можно Map
заполнить пин-кодами с помощью привязки данных для привязки свойства ItemsSource
к 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>
ItemsSource
Данные свойств привязываются к Locations
свойству подключенного модуля представления, который возвращает ObservableCollection
Location
объекты, которые являются пользовательским типом. Каждый Location
объект определяет Address
и Description
свойства типа string
, а Position
также свойство типа Position
.
Внешний вид каждого элемента в IEnumerable
коллекции определяется путем задания ItemTemplate
свойства DataTemplate
, содержащего Pin
объект, который привязывает данные к соответствующим свойствам.
На следующих снимках экрана показана Map
Pin
коллекция с помощью привязки данных:
Выбор внешнего вида элемента во время выполнения
Внешний вид каждого элемента в IEnumerable
коллекции можно выбрать во время выполнения на основе значения элемента, задав ItemTemplateSelector
для свойства значение 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>
В следующем примере показан 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;
}
}
Класс MapItemTemplateSelector
определяет DefaultTemplate
и XamarinTemplate
DataTemplate
свойства, которые задаются различными шаблонами данных. Метод OnSelectTemplate
возвращает XamarinTemplate
значение , которое отображает "Xamarin" в качестве метки при Pin
нажатии элемента, когда элемент имеет адрес, содержащий "Сан-Франциско". Если элемент не имеет адреса, содержащего "Сан-Франциско", OnSelectTemplate
метод возвращает объект DefaultTemplate
.
Примечание.
Вариант использования этой функции — привязка свойств подклассированных Pin
объектов к разным свойствам на основе подтипа Pin
.
Дополнительные сведения о селекторах шаблонов данных см. в разделе "Создание Xamarin.Forms объекта DataTemplateSelector".