I eventually gave up and just made a behavior to handle the binding for me.
public class TileSourceBehavior : DependencyObject, IBehavior
{
public DependencyObject AssociatedObject { get; private set; }
public void Attach(Windows.UI.Xaml.DependencyObject associatedObject)
{
var mapControl = associatedObject as MapControl;
if (mapControl == null)
throw new ArgumentException("TileSourceBehavior can be attached only to MapControl");
AssociatedObject = associatedObject;
}
public void Detach() { }
public static readonly DependencyProperty TileSourceProperty =
DependencyProperty.Register("TileSource", typeof(MapTileSource), typeof(TileSourceBehavior), new PropertyMetadata(null, OnTileSourcePropertyChanged));
public MapTileSource TileSource
{
get { return GetValue(TileSourceProperty) as MapTileSource; }
set { SetValue(TileSourceProperty, value); }
}
private static void OnTileSourcePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var behavior = dependencyObject as TileSourceBehavior;
var mapControl = behavior.AssociatedObject as MapControl;
// remove the existing tile source
var existingTileSource = mapControl.TileSources.FirstOrDefault(t => t.Layer == MapTileLayer.BackgroundReplacement);
if (existingTileSource != null)
mapControl.TileSources.Remove(existingTileSource);
// add the tile source
behavior.TileSource.Layer = MapTileLayer.BackgroundReplacement;
mapControl.TileSources.Add(behavior.TileSource);
}
}
You use it thus, where TileSource
is a MapTileSource property on your ViewModel.
<Maps:MapControl>
<i:Interaction.Behaviors>
<behaviors:TileSourceBehavior TileSource="{Binding Path=TileSource}" />
</i:Interaction.Behaviors>
</Maps:MapControl>