Maps for WPF | ComponentOne
In This Topic
    Layers
    In This Topic

    The Maps control is maintained through many Layers. A map can accommodate more than one layer.

    MapItemsLayer is the easiest way to display items over a map. It inherits from ItemsControl so it supports directly adding UIElement objects or generic data objects with a DataTemplate that can convert them into visual items. Elements added to a MapItemsLayer are positioned using the LongLatProperty field of MapCanvas class.

    Let's look at an example:

     <c1:C1Maps>
            <c1:C1Maps.Layers>
                <c1:MapItemsLayer>
                    <Ellipse Width="20" Height="20" Fill="Red"
                         c1:MapCanvas.LongLat="-79.9247, 40.4587"
                         c1:MapCanvas.Pinpoint="10, 10"/>
                </c1:MapItemsLayer>
            </c1:C1Maps.Layers>
        </c1:C1Maps>
    

    This creates a Maps control in XAML and adds a MapItemsLayer to its Layers collection. Any number of layers can be added to the Layers collection, they will be displayed one on top of the other.

    A map image showcasing the layering feature of Maps control.

    We add one item to the items layer, an ellipse positioned at latitude/longitude (40.4587, -79.9247). Note that these numbers are in reverse order in XAML. This is because LongLat values are represented by a Point structure with its X value corresponding to longitude and its Y value corresponding to latitude (this matches the way maps and X/Y axis are usually oriented).

    In the previous example,  we can also see the PinpointProperty field of MapCanvas class attached property in use. This property configures which point inside the element will match the geographic coordinates set in the LongLat property. In the example case, Pinpoint is set to (10, 10) so that the ellipse will be centered on the LongLat position.

    Let's look at a second example. This time we will create a C1Maps control in code, and populate it with data. We will use the following class:

    public class Place
     {
         public string Name { get; set; }
         public Point LongLat { get; set; }
     }
        
    var map = new C1Maps();
     var itemsLayer = new MapItemsLayer
     {
         ItemsSource = new[]
         {
             new Place {
                 Name = "ComponentOne",
                         LongLat = new Point(-79.92476,  40.45873), },
             new Place {
                 Name = "Greenwich Park",
                         LongLat = new Point(  0.00057,  51.47617), },
         },
         ItemTemplate = itemTemplate
     };
     map.Layers.Add(itemsLayer);
    

    We populate the ItemsSource with instances of the Place class, and we set ItemTemplate to the following DataTemplate defined in the Page's resources:

    <DataTemplate x:Key="itemTemplate">
            <StackPanel Orientation="Horizontal"
                    c1:MapCanvas.LongLat="{Binding LongLat}"
                    c1:MapCanvas.Pinpoint="5, 5">
                <Ellipse Fill="Red" Width="10" Height="10" />
                <TextBlock Text="{Binding Name}" Foreground="White" />
            </StackPanel>
     </DataTemplate>
    

    This DataTemplate binds MapCanvas.LongLat to the LongLat defined in the items and displays the place's Name in a TextBlock.

    Using ItemTemplate and ItemsSource it's easy to load data from a database. You only have to setup a Web service returning a collection of data objects, set the collection as ItemsSource, and create a DataTemplate binding the appropriate values.

    See Also