Xamarin.Forms マップ ピン
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 の作成」を参照してください。