Xamarin.FormsMap コントロールを使用すると、場所を Pin オブジェクトでマークできます。 Pin は、タップしたときに情報ウィンドウを開くマップ マーカーです。
Pin オブジェクトを Map.Pins コレクションに追加すると、ピンがマップ上にレンダリングされます。
Pin クラスには次のプロパティがあります。
string型のAddressは、通常はピンの場所のアドレスを表します。 ただし、アドレスだけでなく、任意のstringのコンテンツも表すことができます。string型のLabelは、通常はピンのタイトルを表します。Position型のPositionは、ピンの緯度と経度を表します。PinType型のTypeは、ピンの種類を表します。
BindableProperty オブジェクトはこれらのプロパティをサポートするので、Pin はデータ バインディングの対象になる場合があります。 データ バインディング Pin オブジェクトの詳細については、「ピンコレクションを表示する」をご覧ください。
さらに、Pin クラスが MarkerClicked と InfoWindowClicked イベントを定義します。 MarkerClicked イベントはピンをタップしたときに発生し、InfoWindowClicked イベントは情報ウィンドウをタップしたときに発生します。 どちらのイベントにも付随する PinClickedEventArgs オブジェクトには、bool 型の HideInfoWindow プロパティが 1 つあります。
ピンを表示する
<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 は、MapSpan オブジェクトで指定する領域を示す Map オブジェクトを作成します。 MapSpan オブジェクトは、緯度と経度の 0.01 度を拡張する Position オブジェクトで表す緯度と経度を中心にしています。 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);
このコード例では、1 つのピンがマップにレンダリングされます。
ピンを操作する
既定では、Pin をタップすると、情報ウィンドウが表示されます。
マップ上の別の場所をタップすると、情報ウィンドウが閉じます。
Pin クラスは、Pin をタップしたときに発生する MarkerClicked イベントを定義します。 このイベントを処理して情報ウィンドウを表示する必要はありません。 代わりに、特定のピンがタップされたことを通知する必要がある場合は、このイベントを処理する必要があります。
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 オブジェクトには、bool 型の HideInfoWindow プロパティが 1 つあります。 このプロパティがイベント ハンドラー内で true に設定されている場合、情報ウィンドウは非表示になります。
ピンの種類
Pin オブジェクトには PinType 型の Type プロパティが含まれていて、ピンの種類を表しています。 PinType 列挙型には、次のメンバーが定義されています。
Genericは、ジェネリック ピンを表します。Placeは、場所のピンを表します。SavedPinは、保存された場所のピンを表します。SearchResultは、検索結果のピンを表します。
ただし、Pin.Type プロパティを任意の PinType メンバーに設定しても、レンダリングしたピンの外観は変更されません。 代わりに、カスタム レンダラーを作成して、ピンの外観をカスタマイズする必要があります。 詳しくは、「マップ ピンのカスタマイズ」を参照してください。
Pin コレクションを表示する
Map クラスには、次のプロパティが定義されています。
ItemsSource:IEnumerable型。表示するIEnumerable項目のコレクションを指定します。ItemTemplate:DataTemplate型。表示される項目のコレクション内の各項目に適用するDataTemplateを指定します。ItemTemplateSelector:DataTemplateSelector型。実行時に項目のDataTemplateを選ぶために使われるDataTemplateSelectorを指定します。
重要
たとえば、ItemTemplate と ItemTemplateSelector の両方のプロパティを設定した場合、ItemTemplate プロパティが優先されます。
データ バインディングを使用して ItemsSource プロパティを IEnumerable コレクションにバインドすることで、Map にピンを設定できます。
<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 プロパティにバインドし、カスタム型である Location オブジェクトの ObservableCollection を返します。 各 Location オブジェクトは string 型の Address と Description プロパティ、および Position 型の Position プロパティを定義します。
IEnumerable コレクション内の各項目の外観は、ItemTemplate プロパティを DataTemplate (データが適切なプロパティにバインドする Pin オブジェクトを含む) に設定することで定義します。
次のスクリーンショットは、データ バインディングを使用して Pin コレクションを表示する Map を示しています。
実行時に項目の外観を選択する
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 メソッドは、項目に "San Francisco" を含むアドレスがある場合に、Pin をタップするとラベルとして "Xamarin" を表示する XamarinTemplate を返します。 項目に "San Francisco" を含むアドレスがない場合、OnSelectTemplate メソッドは DefaultTemplate を返します。
Note
この機能のユース ケースは、Pin サブタイプに基づいて、サブクラス化された Pin オブジェクトのプロパティを異なるプロパティにバインドすることです。
データ テンプレート セレクターの詳細については、「Xamarin.Forms DataTemplateSelector の作成」を参照してください。


