Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

An Insight into Region Creation and RegionAdapters in Prism based WPF Applications

0.00/5 (No votes)
17 Dec 2015 2  
To work with Regions effectively in a Prism based WPF application, we must understand the relationship between WPF Controls, RegionAdapters and Regions. In this articles, we will learn about process of Region creation and critical role played by RegionAdapters with a demo application.

Introduction

To create and use a Region effectively within a Prism based WPF application, it is critical to understand the relationship between WPF Controls, RegionAdapters and Regions. RegionAdapters pays a very critical role in Region creation process and determine its behaviours. In this articles, we will learn about process of Region creation and role of RegionAdapters in it. We will create a demo application using WPF and Prism 4. We will use all three kind of RegionAdapters provided by Prism Framework (ContentControlRegionAdapter, ItemsControlRegionAdapter and SelectorRegionAdapter) in it.

Prerequisites: I assume you would be having basic understanding of WPF and Prism Framework. Prism is a framework for building Composite Applications using WPF/Silverlight. I have explained step by step and demonstrated such composite application in an article series named as "Composite Applications with Prism in WPF". For more learning about Prism, please have a look at Prism Basic Introduction and Prism Page on MSDN, and few more things about Prism.

Outlines

  • Regions and RegionAdapters
  • Region Creation Process
  • WPF Controls and RegionAdapters
  • Activate and Deactivate Views
  • Show and Hide View Extension
  • Learning Summary
  • Overview of Demo

Regions and RegionAdapters

Region makes standard WPF controls (like Button, ListBox, ComboBox etc.) to behave like a dynamic container of Views along with certain other behaviours. At runtime, we can add, remove, activate, deactivate, show and hide a View in a region. RegionAdapters plays a central role to make this possible. A Region can adopt Views from different Modules and same we will do while creating demo application.

There are two main concepts related to Region: RegionManager and RegionAdapters. The RegionManager is responsible for creating and maintaining a collection of regions for host WPF controls. RegionAdapters are responsible for creating a region and associating it with the host WPF controls. In a typical Prism application we often need to understand and choose among different kind of WPF controls to host Region. By choosing a particular WPF host control, we indirectly choose a particular RegionAdapter and Region. This article will explain about those implicit choices and help to take better decisions while creating a Region.

Sometime we need to create custom RegionAdapters and Regions too. In Prism library, out of the box, three kind of RegionAdapters and respective Regions are provided. We will look into those in detail further. In next section we will explore Region creation process.

Region Creation Process

In XAML, we can create a Region with following code:

<ListBox Name="MainRegion" prism:RegionManager.RegionName="MainRegion"/>

In above code, we are using a standard WPF ListBox control and setting an AttachedProperty of RegionManager called RegionName. RegionManager class that AttachedProperty defined as per below code taken from Prism library source code. Focus on method DependencyProperty.RegisterAttached, which is used to create an AttachedProperty (not just Register method which creates a DependencyProperty).

public static readonly DependencyProperty RegionNameProperty = DependencyProperty.RegisterAttached(
            "RegionName",
            typeof(string),
            typeof(RegionManager),
            new PropertyMetadata(OnSetRegionNameCallback));

RegionManager looks into mapping defined between for based on particular WPF Controls and RegionAdapters and create a RegionAdapter as per the mapping given. Such mapping is defined in class "Bootstrapper.cs" as given below. It says if WPF control is a type of Selector, ItemsControl or ContentControl then RegionManager will create a SelectorRegionAdapter, ItemsControlRegionAdapter or ContentControlRegionAdapter respectively. In next section we will look into the relationship between WPF controls and RegionAdapters in details.

protected virtual RegionAdapterMappings ConfigureRegionAdapterMappings()
        {
            RegionAdapterMappings regionAdapterMappings = ServiceLocator.Current.GetInstance<RegionAdapterMappings>();
            if (regionAdapterMappings != null)
            {
                regionAdapterMappings.RegisterMapping(typeof(Selector), ServiceLocator.Current.GetInstance<SelectorRegionAdapter>());
                regionAdapterMappings.RegisterMapping(typeof(ItemsControl), ServiceLocator.Current.GetInstance<ItemsControlRegionAdapter>());
                regionAdapterMappings.RegisterMapping(typeof(ContentControl), ServiceLocator.Current.GetInstance<ContentControlRegionAdapter>());
            }
            return regionAdapterMappings;
        }

And finally RegionAdapter create a specific type of Region for you. By default ContentControlRegionAdapter, ItemsControlRegionAdapter and SelectorRegionAdapter creates an instance of SingleActiveRegion, AllActiveRegion and Region class respectively. Following is pictorial description of How a Region is being created and associated with WPF Control:

Install Prism Framework
 

WPF Controls and RegionAdapters

As we discussed in last section, based on mapping between WPF Controls and RegionAdapters, RegionManager creates a RegionAdapters. There are blow three kind of RegionAdapters provided by Prism library:

  1. ContentControlRegionAdapter: This adapter adapts controls of type System.Windows.Controls.ContentControl and derived classes.
  2. ItemsControlRegionAdapter: This adapter adapts controls of type System.Windows.Controls.ItemsControl and derived classes.
  3. SelectorRegionAdapter: This adapter adapts controls derived from the class System.Windows.Controls.Primitives.Selector.

It is critical to choose appropriate WPF Control while defining a region in XAML, so that appropriate RegionAdapter and Region gets created to fulfil our requirement. We can provide new mapping and create Custom RegionAdapters too, but first thing in hand we have to choose appropriate WPF control while creating Region. Below image show relationship between the controls which can be used to create Regions:

Relationship between WPF Controls

As per above image ContentControl and ItemsControl are parallel in hierarchy and both inhetited from Control and implement IAddChild interface. ContentControl supposed to host a single item or View.

But ItemsControl implements an additional interface called as IGeneratorHost to facilitate ItemContainers behaviour as it need to have multiple items. IGeneratorHost is an interface through which an ItemContainerGenerator communicates with its host.

Finally Selector is inherited from ItemsControl and provide addition functionality to select an item among multiple hosted items. Selector is an abstract class must use any concrete class inherited from Selector. To find out which controls can be used as Selector, we can visit Selector documentaion on MSDN. As shown on this page, we can use ComboBox, ListBox or TabControl etc. as Selector.

Selector Class

Similarly we can find out the controls inherited from ContentControl at ContentControl documentation and ItemsControl at ItemsControl documentation on MSDN. At ContentControl documentation we can see that even Label and Button (derivative of ButtonBase) can be used to create a Region. In demo code we can verify it by commenting out existing line to create Region and un-comment any other similar line with some another control.

Activate and Deactivate Views

Activation and Deactivation are used to mark a View active and deactivated. To make an efficient application, we may need to deactivate and activate Views at per scenarios. If views have implemented IActiveAware interface we can define actions to be done on activation or deactivation. A real time based example of IActiveAware interface is explained at this article. Activation and Deactivation is supported by only two RegionAdapters: ContentControlRegionAdapter and SelectorRegionAdapter.

As ContentControlRegionAdapter contains single View so if you deactivate current view, Region will be empty and if you activate some new view, the new View will be the content of the region and previous View will be deactivated.

In case of SelectorRegionAdapter you can activate and deactivate View. But Region created with SelectorRegionAdapter shows both active and deactivated Views.

ItemsControlRegionAdapter does not support Deactivation and it will throw an InvalidOperationException. If you try to deactivate a view within a Region created using ItemsControlRegionAdapter, will get an InvalidOperationException exception saying: "An unhandled exception of type 'System.InvalidOperationException' occurred in Microsoft.Practices.Prism.dll" with Additional information: Deactivation is not possible in this type of region.

Show and Hide View Extension

As we discussed in above section, SelectorRegionAdapter shows both active and deactivated Views and ItemsControlRegionAdapter does not support deactivation at all. In those cases if we need to hide/show Views, such functionality is not provided by Prism. So we need to write code to implement such functionality. There is a nice blog post by Matias Bonaventura with code of RegionExtensions class having hide and show functionality. We have used that class in our demo application to provide show and hide capabilities.

ContentControlRegionAdapter support only single View, so activate and show behaves in same way.

Learning Summary

Below table provides summary of Controls Used, RegionAdapters and other related concepts so far:

WPF Control Used to Create Region ContentControl or its Derived Control ItemControl or its Derived Control Selector's Derived Control
General Use of Control Represents a control with a single piece of content of any type Represents a control that can be used to present a collection of items Represents a control that allows a user to select items from among its child elements
RegionAdapter Class Used ContentControlRegionAdapter ItemsControlRegionAdapter SelectorRegionAdapter
Region Class Used SingleActiveRegion AllActiveRegion Region
How Many Active Views Single View (Always Active and Visible), if you call deactivate/hide on that single view it will make Content Control empty Multiple View (All Active), calling Deactivate throw exception, but you can hide views Multiple Views both active and Deactivated views are visible. You need to call hide/show to set visibility for active / deactivated view
Deactivate View Will work but it will empty the region as Deactivation is called on single content view Will throw InvalidOperationException exception saying: "An unhandled exception of type 'System.InvalidOperationException' occurred in Microsoft.Practices.Prism.dll" with Additional information: Deactivation is not possible in this type of region. Will work
Active vs Visible Active view will be visible as it is set as the content of the ContentControl (as there is only one view) All views (by default Active) are visible. (until we wrote extension to hide) All views (active and deactivated) are visible
Hide vs Deactivation As only single view is supported. The Active view cannot be hidden and a deactivated view cannot be visible Hide works but Deactivate will throw an exception Call Hide explicitly as Active / Deactivated View. By default even Deactivate view will be visible

Overview of Demo

We will explain in brief about demo application and few critical steps and how to do experiments with demo. I hope most of the code in demo is self-explanatory. Feel free to write a comment if you need any explanation.

The Demo solution is having three projects:

  1. RegionAdaptersDemoApp : Created using standard WPF Project template. It has Shell as MainWindow where Regions are defined. In Region we are using Views defined in other two module projects (ModuleA and ModuleB).
  2. RegionAdaptersDemoApp.Module A: Created using Class Library Project template. Represent Module A and having two Views: View1 and View2.
  3. RegionAdaptersDemoApp.ModuleB : Created using Class Library Project template. Represent Module B and having two Views: View3 and View4.

We are using Prism 4 and WPF project targeting .NET Framework 4, so that demo app can run on Visual Studio 2010 onwards without addition setups. After creation of projects, we should install "Prism.UnityExtensions" nuget package by running following command in Nuget Package Console:

Get-Project -All | Install-Package Prism.UnityExtensions -Version 4.0.0

Below screenshot shows Nuget Package Console:

Installing Prism 4

In ModuleA, while adding View, add a WPF User Controls (called as "View1" and "View2") as shown below:

Adding WPF User Control

Add reference to "System.XAML" if already not included in that project (because it was created using Class Library project template). ModuleB is very similar to ModuleA only.

Inside RegionAdaptersDemoApp project, look into MainWindow.xaml, currently we are having Region created using ListBox. And there are commented codes which can be used to experiment with other WPF controls to create Region. And you can use Button called "View Region Creation Detail" to see the details of classes used for Region while using that WPF Control.

In Control section, you can choose views and Add/Remove/Activate/Deactivate/Show/Hide operations can be done if applicable as per current scenario, otherwise we will get exception thrown.

Final demo application will look like:

Adding WPF User Control
 

Conclusion

In this article, we learned about relationship between WPF Controls, RegionAdapters and Regions. Hope it will help you to take an informed decision while creating a Region in Prism based WPF application. Your comments / suggestions and queries are most welcome. Thanks.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here