Xamarin.Forms Закрепление карты

Элемент Xamarin.FormsMap управления позволяет помечать расположения объектами Pin . Маркер Pin карты, который открывает окно сведений при нажатии:

Снимок экрана: закрепление карты и его окно сведений в iOS и Android

Pin При добавлении Map.Pins объекта в коллекцию пин-код отображается на карте.

Класс Pin имеет следующие свойства:

  • AddressstringТип , который обычно представляет адрес для расположения пин-кода. Однако это может быть любое string содержимое, а не только адрес.
  • Labelтипа string, который обычно представляет заголовок пин-кода.
  • PositionPositionтип, представляющий широту и долготу закрепления.
  • 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.

Этот пример кода приводит к отрисовке одного пин-кода на карте:

Снимок экрана: закрепление карты в iOS и Android

Взаимодействие с закреплением

По умолчанию отображается окно сведений:Pin

Снимок экрана: закрепление карты и его окно сведений в iOS и Android

Касание в другом месте карты закрывает окно сведений.

Класс 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 коллекция с помощью привязки данных:

Снимок экрана: карта с закрепленными контактами с данными в iOS и Android

Выбор внешнего вида элемента во время выполнения

Внешний вид каждого элемента в 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".