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 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.
{
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)
<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:
- 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.
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.