Joshua Rogers
Joshua Rogers

Reputation: 3548

How to add Z-Index to XAML controls in Windows 10 MapControl

1 it was quite easy to add pushpins and whatever you liked to several layers, clear those layers and you could make sure that some items where in front of others. With Windows 10, that control is gone, and replaced by a control with half the things I really need but, with 3D and scenes (things that I don´t use)

My First attempt was, ok, MapPolygon has ZIndex because it inherits from MapElement and implements

internal interface IMapElement
{
    System.Boolean Visible { get; set; }
    System.Int32 ZIndex { get; set; }
}

Great, lets implement that in my UserControl, so the map control knows how to draw each element. SURPRISE! that interface is internal, you cannot do anything but stare at it.

Second attampet, maybe they use a canvas to draw the elements, and Canvas has a ZIndex, let´s well, needless to say it didn´t work

pin.SetValue(Canvas.ZIndexProperty);

Can anybody please tell me if there is anything like layers in the UWP MapControl or if there is a way to tell that MapControl in which index to draw the items?

Regards.

Upvotes: 3

Views: 4241

Answers (2)

Jakub Krampl
Jakub Krampl

Reputation: 1794

I am not sure whether it solves your problem but definitely it solved my issue and it could be helpful for other people as well.

public class MapControl : DependencyObject
{

    #region Dependency properties

    public static readonly DependencyProperty ZIndexProperty = DependencyProperty.RegisterAttached("ZIndex", typeof(int), typeof(MapControl), new PropertyMetadata(0, OnZIndexChanged));

    #endregion


    #region Methods

    public static int GetZIndex(DependencyObject obj)
    {
        return (int)obj.GetValue(ZIndexProperty);
    }

    private static void OnZIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ContentControl us = d as ContentControl;

        if (us != null)
        {
            // returns null if it is not loaded yet
            // returns 'DependencyObject' of type 'MapOverlayPresenter'
            var parent = VisualTreeHelper.GetParent(us);

            if (parent != null)
            {
                parent.SetValue(Canvas.ZIndexProperty, e.NewValue);
            }
        }
    }

    public static void SetZIndex(DependencyObject obj, int value)
    {
        obj.SetValue(ZIndexProperty, value);
    }

    #endregion

}

Namespaces

xmlns:maps="using:Windows.UI.Xaml.Controls.Maps"
xmlns:mapHelper="using:yournamespace"

Control

<maps:MapControl>
    <maps:MapItemsControl ItemsSource="...">
        <maps:MapItemsControl.ItemTemplate>
            <DataTemplate x:DataType="...">
                <YourTemplate mapHelper:MapControl.ZIndex="{x:Bind ZIndex, Mode=OneWay}" />
            </DataTemplate>
        </maps:MapItemsControl.ItemTemplate>
    </maps:MapItemsControl>
</maps:MapControl>

Upvotes: 2

Pedro G. Dias
Pedro G. Dias

Reputation: 3222

Can't you do this declaratively? Consider the following XAML:

<maps:MapControl x:Name="myMap" HorizontalAlignment="Left">
  <maps:MapItemsControl x:Name="MapItems" ItemsSource="{Binding}">
    <maps:MapItemsControl.ItemTemplate>
      <DataTemplate>
        <Button x:Name="MapItemButton" Background="Transparent">
          <StackPanel>
            <Border Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
              <TextBlock Text="{Binding Title}"/>
            </Border>
            <Image Source="{Binding ImageSourceUri}" maps:MapControl.Location="{Binding Location}">
              <Image.Transitions>
                <TransitionCollection>
                  <EntranceThemeTransition/>
                </TransitionCollection>
              </Image.Transitions>
            </Image>
          </StackPanel>
        </Button>
      </DataTemplate>
    </maps:MapItemsControl.ItemTemplate>
  </maps:MapItemsControl>
</maps:MapControl>

Here, I'm basically binding images (mapelements) directly to the map's location using regular XAML features. Use grid layers, stackpanels and whatnots to control what goes on top, what goes under etc. You can also construct this via codebehind of course.

Upvotes: 0

Related Questions