Binding a MapIcon in XAML

2019-06-24 11:01发布

问题:

I'm trying to use a MapControl, showing a MapIcon for the currently viewed location.

In my XAML, I've got:

<Maps:MapControl x:Name="MapControl" ZoomLevel="14" Center="{Binding Geopoint, Mode=OneWay}" Margin="-12,0,-12,0" Tapped="directions_Click" Height="200" MapServiceToken="{StaticResource BingMapsKey}" PanInteractionMode="Disabled" RotateInteractionMode="Disabled">
    <Maps:MapIcon Location="{Binding Geopoint}" Title="{Binding AttractionName}" />
</Maps:MapControl>

The items that I'm binding to are being used elsewhere on the page (e.g. the map centres on the correct location), but the MapIcon does not show, nor give any hint as to why?

As far as I can see from MSDN I should be able to bind in this manner (although the example specifically for <MapIcon>s is adding them dynamically, it does show other XAML objects being bound directly in the XAML). Am I marking up the XAML wrong here?

回答1:

I've ended up building my own pushpin, via XAML:

 <Maps:MapControl x:Name="MapControl" ZoomLevel="14" Center="{Binding Geopoint, Mode=OneWay}" Margin="-12,0,-12,0" Tapped="directions_Click" Height="200" MapServiceToken="{StaticResource BingMapsKey}" PanInteractionMode="Disabled" RotateInteractionMode="Disabled">
     <Grid HorizontalAlignment="Left" Maps:MapControl.Location="{Binding Geopoint}" Maps:MapControl.NormalizedAnchorPoint="0,1">
         <Grid.RowDefinitions>
             <RowDefinition Height="*" />
             <RowDefinition Height="*" />
         </Grid.RowDefinitions>

         <Border Background="{ThemeResource SystemControlBackgroundAccentBrush}" Grid.Row="0">
             <TextBlock Text="{Binding AttractionName}" HorizontalAlignment="Left" />
         </Border>
         <Polygon Points="0,0 12.5,0 0,20" Fill="{ThemeResource SystemControlBackgroundAccentBrush}" StrokeThickness="0" Grid.Row="1" />
     </Grid>
 </Maps:MapControl>

This allows the position to be bound (via Maps:MapControl.Location="{Binding Geopoint}") and the relative position can be set so the point remains at the correct location (via Maps:MapControl.NormalizedAnchorPoint="0,1" - i.e. bottom left of the pin content)

Whilst this isn't using a MapIcon, This gives a look and feel to how our app showed locations with Windows Phone 7.x/8.x so may be helpful for others wanting similar.



回答2:

As you mentioned, the Location and Title can bind to Geopoint and AttractionName. But to display MapIcon on the MapControl, we need to add MapIcon to its MapElements collection programmatically.

For example:

In the Loaded event of the MapControl.

private void MapControl_Loaded(object sender, RoutedEventArgs e)
{
    MapControl.MapElements.Add(MyMapIcon);
}

After this the MapIcon can show on the MapControl like the image. But you will find there is a string of class name on the top left corner of MapControl.

It is because you add the MapIcon as implicit children of the MapControl. It is equivalent to add MapIcon in MapItemsControl like the following XAML code.

<Maps:MapControl x:Name="MapControl" ZoomLevel="14" Center="{Binding Geopoint, Mode=OneWay}" Margin="-12,0,-12,0"  Height="200" PanInteractionMode="Disabled" RotateInteractionMode="Disabled"   Loaded="MapControl_Loaded">
    <Maps:MapItemsControl>
        <Maps:MapIcon x:Name="MyMapIcon" Location="{Binding Geopoint}" Title="{Binding AttractionName}" />
    </Maps:MapItemsControl>
</Maps:MapControl>

MapItemsControl can displays XAML user interface elements such as a Button, a HyperlinkButton, or a TextBlock by adding them as Children of the MapControl. The MapIcon can not show on the MapControl, so it show its class name.

As a workaround we can put MapIcon in the Resources to solove the problem. For example:

<Page.Resources>
    <Maps:MapIcon x:Name="MyMapIcon" Location="{Binding Geopoint}" Title="{Binding AttractionName}" />
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Maps:MapControl x:Name="MapControl" ZoomLevel="14" Center="{Binding Geopoint, Mode=OneWay}" Margin="-12,0,-12,0" Tapped="directions_Click" Height="200" MapServiceToken="{StaticResource BingMapsKey}" PanInteractionMode="Disabled" RotateInteractionMode="Disabled" Loaded="MapControl_Loaded">
    </Maps:MapControl>
</Grid>


回答3:

I have had a similar problem with the MapControl in UWP. My solution was to use the MapControl as a ItemsControl and display a collection of elements. The following code just displays an image, but you can wrap the content of the DataTemplate in a Grid and display an Image and a TextBlock for example.

    <Maps:MapControl>                        
        <Maps:MapItemsControl x:Name="MapItems" ItemSource="{Binding Items}">
            <Maps:MapItemsControl.ItemTemplate>
                <DataTemplate x:DataType="m:model">
                    <Image Source="{x:Bind ImgSource}" Maps:MapControl.Location="{x:Bind Location}" Width="50" Height="50" Margin="-25,-50,0,0" />
                </DataTemplate>
            </Maps:MapItemsControl.ItemTemplate>
        </Maps:MapItemsControl>
    </Maps:MapControl>

Hope this helps!