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.
Awesome use of Prism, I’ve passed this post to the Prism team.
Where did you get the Texas locations?