31 Aug
2011

Prism-fy the Bing Maps WPF Control (Beta)

Category:UncategorizedTag: , , , , , , :

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.

Find me

RSS
Facebook
Twitter
LinkedIn
SOCIALICON
SOCIALICON

Disclaimer

The opinions and content expressed here are my own and not those of my employer.