1

I have a MapControl in UWP:

<maps:MapControl x:Name="BikeMap" ZoomLevel="17" Center="{Binding CenterPoint, Mode=TwoWay}">
    <maps:MapItemsControl x:Name="MapItems" ItemsSource="{Binding BikePoints}"
                        ItemTemplate="{StaticResource BikePointTemplate}"/>
</maps:MapControl>

and am adding MapElements using XAML data templates, my ItemsSource is a list of simple objects.

But, UWP doesn't seem to provide a way to specify the DataType of a DataTemplate and the MapItemsControl doesn't have a property for setting a DataTemplateSelector.

Does anyone know how I can use multiple data templates with the MapItemsControl and have the relevent data template selected based on the object type within the ItemsSource?

S. Matthews
  • 355
  • 2
  • 9
Glen Thomas
  • 10,190
  • 5
  • 33
  • 65
  • It's hard to believe that the UWP MapItemsControl is not derived from ItemsControl. You may perhaps choose a different map library where the MapItemsControl is actually an ItemsControl with a working ItemTemplateSelector, like [this one](https://xamlmapcontrol.codeplex.com/). – Clemens Oct 11 '16 at 09:27
  • Hello @JayZuo-MSFT I haven't tried it yet as have been busy. I will get round to it soon! Thanks – Glen Thomas Oct 19 '16 at 09:12

1 Answers1

5

MapItemsControl Class does not have a property for setting DataTemplateSelector. To achieve what you want, we can take advantage of ContentControl by setting it as the template content in DataTemplate and then using ContentControl.ContentTemplateSelector property to set DataTemplateSelector.

Following is a simple sample:

XAML:

<Page x:Class="UWPApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:Maps="using:Windows.UI.Xaml.Controls.Maps"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:local="using:UWPApp"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">
    <Page.Resources>
        <DataTemplate x:Key="GreenDataTemplate">
            <StackPanel Background="Green">
                <TextBlock Margin="5"
                           Maps:MapControl.Location="{Binding Location}"
                           Maps:MapControl.NormalizedAnchorPoint="0.5,0.5"
                           FontSize="20"
                           Text="{Binding Name}" />
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="RedDataTemplate">
            <StackPanel Background="Red">
                <TextBlock Margin="5"
                           Maps:MapControl.Location="{Binding Location}"
                           Maps:MapControl.NormalizedAnchorPoint="0.5,0.5"
                           FontSize="20"
                           Text="{Binding Name}" />
            </StackPanel>
        </DataTemplate>

        <local:MyTemplateSelector x:Key="MyTemplateSelector" GreenTemplate="{StaticResource GreenDataTemplate}" RedTemplate="{StaticResource RedDataTemplate}" />
    </Page.Resources>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Maps:MapControl x:Name="MyMap" MapServiceToken="MapServiceToken">
            <Maps:MapItemsControl x:Name="MyMapItemsControl" ItemsSource="{Binding}">
                <Maps:MapItemsControl.ItemTemplate>
                    <DataTemplate>
                        <ContentControl Content="{Binding}" ContentTemplateSelector="{StaticResource MyTemplateSelector}" />
                    </DataTemplate>
                </Maps:MapItemsControl.ItemTemplate>
            </Maps:MapItemsControl>
        </Maps:MapControl>
    </Grid>
</Page>

Code-Behind:

public class MyTemplateSelector : DataTemplateSelector
{
    public DataTemplate GreenTemplate { get; set; }
    public DataTemplate RedTemplate { get; set; }

    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    {
        if (item != null)
        {
            if (item is GreenPOI)
            {
                return GreenTemplate;
            }

            return RedTemplate;
        }

        return null;
    }
}

public class POI
{
    public string Name { get; set; }

    public Geopoint Location { get; set; }
}

public class GreenPOI : POI { }

public class RedPOI : POI { }

This is just for example. In the sample, I used two data template with different background and I create a custom DataTemplateSelector which can choose DataTemplate based on the object type. And if you have several object types, you can also refer to this answer: How to associate view with viewmodel or multiple DataTemplates for ViewModel?

Community
  • 1
  • 1
Jay Zuo
  • 15,653
  • 2
  • 25
  • 49
  • This was a great solution however the map control won't add more items after initial bind and render... I cannot seem to figure out why. Only the initial items are drawn. – Bobby Cannon Sep 05 '19 at 01:26
  • Ah ha, [new ObservableCollection] fails to update but [new ObservableCollection] works... not sure why that is. – Bobby Cannon Sep 05 '19 at 01:32