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
。
顯示釘選
<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
集合,並在 其 Position
屬性所指定的位置上Map
繪製。 如需結構的相關信息 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
點選時會顯示其資訊視窗:
點選地圖上的其他地方會關閉信息視窗。
類別 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
成員並不會變更轉譯釘選的外觀。 相反地,您必須建立自定義轉譯器來自定義釘選外觀。 如需詳細資訊,請參閱 自定義地圖釘選。
顯示 PIN 集合
類別 Map
會定義下列屬性:
ItemsSource
型IEnumerable
別為 的 ,指定要顯示的專案IEnumerable
集合。ItemTemplate
型DataTemplate
別為 的 ,指定要DataTemplate
套用至所顯示專案集合中每個專案的 。ItemTemplateSelector
型DataTemplateSelector
別為 的 ,指定DataTemplateSelector
將在運行時間為項目選擇DataTemplate
的 。
重要
設定 ItemTemplate
和 ItemTemplateSelector
屬性時ItemTemplate
,屬性會優先使用。
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
連接的 viewmodel 屬性,該屬性會ObservableCollection
Location
傳回 物件的 ,這是自定義型別。 每個Location
物件都會Address
定義 型string
別 的 和 Description
屬性,以及 Position
型別 Position
的屬性。
集合中 IEnumerable
每個項目的外觀都是藉由將 屬性設定 ItemTemplate
為 DataTemplate
Pin
,其中包含數據系結至適當屬性之 物件的 。
下列螢幕快照顯示 Map
使用資料系結來 Pin
顯示集合:
選擇運行時間的項目外觀
您可以藉由將 屬性設定ItemTemplateSelector
為 DataTemplateSelector
,在執行時間根據專案值選擇集合中IEnumerable
每個項目的外觀:
<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
屬性,這些屬性會設定為不同的數據範本。 當專案具有包含 「San Francisco」 的位址時,此方法 OnSelectTemplate
會 XamarinTemplate
傳回 ,當點選 時 Pin
,會將 「Xamarin」 顯示為標籤。 當項目沒有包含 「San Francisco」 的位址時, OnSelectTemplate
此方法會傳 DefaultTemplate
回 。
注意
這項功能的使用案例是根據Pin
子類型,將子類別Pin
對象的屬性系結至不同的屬性。
如需數據範本選取器的詳細資訊,請參閱 建立 Xamarin.Forms DataTemplateSelector。