Prism-fy the Bing Maps WPF Control (Beta)

August 31st, 2011

If you know me or know of me you are aware that I am a big Prism advocate/evangelist.  You may have also noticed that I have been playing around with the new Bing Maps WPF control.  So it shouldn’t surprise you that I would find a way to compose a Bing Map of loosely coupled MapLayers at runtime using Prism.

The concept is simple.  We want a Bing Maps application that can be extended at runtime.  By extended, I mean that I want the ability to add new elements/modules to the Map at runtime.  The important thing about these elements/modules is that they can come from anywhere and they should be loosely coupled from the Map as well as other elements/modules that may exist on the Map.

Luckily for us this is extremely simple to accomplish.  All we have to do is create a custom RegionAdapter, register it with our Prism application, and then apply it to our Bing Map control.  So let’s start with the RegionAdapter.

public class MapRegionAdapter : RegionAdapterBase<Map>
{
    public MapRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
        : base(regionBehaviorFactory)
    {

    }

    protected override void Adapt(IRegion region, Map regionTarget)
    {
        region.Views.CollectionChanged += (s, e) =>
        {
            if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
            {
                foreach (FrameworkElement element in e.NewItems)
                    regionTarget.Children.Add(element);
            }
            else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
            {
                foreach (FrameworkElement element in e.OldItems)
                    if (regionTarget.Children.Contains(element))
                        regionTarget.Children.Remove(element);
            }
        };
    }

    protected override IRegion CreateRegion()
    {
        return new AllActiveRegion();
    }
}

Now in the Bootstrapper we need to register our mapping.

protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
    RegionAdapterMappings mappings = base.ConfigureRegionAdapterMappings();
    mappings.RegisterMapping(typeof(Map), Container.Resolve<MapRegionAdapter>());
    return mappings;
}

Now we simply give the Map a region name. (this is actually all the shell has in it)

<Grid>
    <bing:Map prism:RegionManager.RegionName="{x:Static inf:RegionNames.MapRegion}" Center="40,-95" ZoomLevel="4" />
</Grid>

That is all there is to it.  You can now start injecting modules onto the Map at runtime.  Lets look at my two modules I am using as an example.  Here is the structure of my application:

image

  • ModuleA will inject a MapPolygon in the Shape of Texas.
  • ModuleB is the Earthquake application we built in an earlier post.
  • Infrastructure is the project where shared code goes, in this case our MapRegionAdapter
  • BingMapsPrismfiedDemo is of course our shell project.

This is what the application looks like at runtime when both modules have been injected into it.

image

Now I can easily add more layers to this map as I see fit.  As always, Download the Source and start playing.  You may want to add MEF support as well.

  • http://molenator.myopenid.com/ molenator

    Awesome use of Prism, I’ve passed this post to the Prism team.

  • Korhanmustafa

    Where did you get the Texas locations?