How to: Create a Custom Region Adapter

This topic assumes that you are familiar with regions. For more information, see the UI Composition technical concept.


To expose a UI control as a region, a region adapter is used. Region adapters are responsible for creating a region and associating it to the control. By doing this, developers can manage the UI control's contents in a consistent way through the IRegion interface. Each region adapter adapts a particular type of UI control. The Composite Application Library provides three region adapters out-of-the-box:

  • ContentControlRegionAdapter. This adapter adapts controls of type System.Windows.Controls.ContentControl and derived classes.
  • SelectorRegionAdapter. This adapter adapts controls derived from the class System.Windows.Controls.Primitives.Selector, such as the System.Windows.Controls.TabControl control.
  • ItemsControlRegionAdapter. This adapter adapts controls of type System.Windows.Controls.ItemsControl and derived classes.
The Silverlight version of the Composite Application Library contains a fourth region adapter named TabControlRegionAdapter. This is because the TabControl control in Silverlight 3 does not extend the Selector class and has a behavior that is different from its WPF counterpart.

There are some scenarios in which none of the preceding region adapters suit the developer needs. In those cases, custom region adapters can be created to adapt controls not supported by the Composite Application Library out-of-the-box.

The purpose of this topic is to explain how to create custom region adapters.


This topic assumes that you already have a solution based on the Composite Application Library. For information about how to do this, see How to: Create a Solution Using the Composite Application Library.


Region adapters implement the Microsoft.Practices.Composite.Regions.IRegionAdapter interface. This interface defines a single method named Initialize that takes the object to adapt and returns a new region associated with the adapted control. The interface definition is shown in the following code.

public interface IRegionAdapter
    IRegion Initialize(object regionTarget, string regionName);

To create a region adapter, you implement the IRegionAdapter interface. The following procedure describes how to implement the IRegionAdapter interface.

To create a custom region adapter

  1. Add a new class to your solution.
  2. Add the following using statements at the top of the class file. You will use them to refer to region elements in the Composite Application Library.
    using Microsoft.Practices.Composite.Presentation.Regions;
    using Microsoft.Practices.Composite.Regions;
  3. Change your class signature to inherit from the RegionAdapterBase<T> base class, where T is the type of the UI control to adapt. This base class implements the IRegionAdapter interface and provides common behavior and template methods you must override in your derived class. The following code example shows the definition of the ContentControlRegionAdapter class. Note that the type parameter of the base class is ContentControl. This means the region adapts controls of this type.
    public class ContentControlRegionAdapter : RegionAdapterBase<ContentControl>
  4. Implement the CreateRegion template method. This is an abstract method defined in the RegionAdapterBase class; it should return a region instance (an object that implements the IRegion interface) to be associated with the adapted control. The Composite Application Library provides the following region implementations out-of-the-box:
    • Region. This region allows multiple active views. This is the region used for controls derived from the Selector class.
    • SingleActiveRegion. This region allows a maximum of one active view at a time. This is the region used for ContentControl controls.
    • AllActiveRegion. This region keeps all the views in it as active. Deactivation of views is not allowed. This is the region used for ItemsControl controls.

    The following code shows the CreateRegion method implementation included in the ContentControlRegionAdapter class. Because ContentControl controls can contain a single piece of content at a time, a SingleActiveRegion region is utilized.

    protected override IRegion CreateRegion()
        return new SingleActiveRegion();
  5. Override the abstract Adapt method. This template method has to adapt the control to the region created in the previous step. The Adapt method takes two parameters: the region with which the adapted control has to be associated and the control to adapt. The method's signature is shown in the following code.
    protected abstract void Adapt(IRegion region, T regionTarget);

    An example implementation of the Adapt method taken from the ContentControlRegionAdapter region adapter is shown in the following code.

    protected override void Adapt(IRegion region, ContentControl regionTarget)
        bool contentIsSet = regionTarget.Content != null;
        contentIsSet = contentIsSet || (BindingOperations.GetBinding(regionTarget, ContentControl.ContentProperty) != null);
        if (contentIsSet)
            throw new InvalidOperationException("Your custom exception message");
        region.ActiveViews.CollectionChanged += delegate
            regionTarget.Content = region.ActiveViews.FirstOrDefault();
        region.Views.CollectionChanged +=
            (sender, e) =>
                if (e.Action == NotifyCollectionChangedAction.Add && region.ActiveViews.Count() == 0)
    The hardcoded string in the preceding code snippet is used only to provide a working code sample and is not a best practice. For example, it would be a better practice to store the string in a resources file, as shown in the ContentControlRegionAdapter class provided by the Composite Application Library.

    Note that in the preceding code, the content of the adapted control is set to the first active view of the region whenever the collection of active views of the region changes. Also note that conditional compiling is used for WPF-specific validation because you cannot retrieve the bindings' metadata in Silverlight.

  6. Optionally, override the AttachBehaviors method. This method is used to attach special logic to customize the region behavior.
The region adapter will be registered as a singleton service and will be kept alive throughout the application's lifetime, so make sure not to keep references to possibly shorter lived objects, such as UI controls or region instances.

Region adapter mappings are used by the region manager service to associate the correct region adapters for XAML-defined regions. The following procedure describes how to create a region adapter mapping to map the custom region adapter created in the previous procedure with the UI control type the region adapter adapts.

To register the custom region adapter mapping

  1. In your application's bootstrapper class file, add the following using statement at the top of the file. You will use it to refer to region elements in the Composite Application Library.
    using Microsoft.Practices.Composite.Presentation.Regions;
  2. Override the ConfigureRegionAdapterMappings method to add your own custom region adapter mappings. To do this, perform the following steps:
    1. Invoke the base implementation of the ConfigureRegionAdapterMappings method to obtain the region adapter mappings registered by default by the UnityBootstrapper class. Region mappings are represented by an instance of the RegionAdapterMappings class.
    2. Register your custom mapping by invoking the RegisterMapping method on the region mappings instance. This method accepts the following parameters: the type of the control to adapt and an instance of the corresponding region adapter.
    3. Return the region mappings.

    The following code example shows how to add a mapping for a control of type ControlToAdapt and a region adapter named CustomRegionAdapter.

    protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
        RegionAdapterMappings mappings = base.ConfigureRegionAdapterMappings();
        mappings.RegisterMapping(typeof(ControlToAdapt), new CustomRegionAdapter());
        return mappings;


You will have a new custom region adapter created and a mapping registered. You can now use the RegionManager.RegionName property to associate a region to the target control with the adapter you created.

More Information

For more information about extensibility points in the Composite Application Library, see Customizing the Composite Application Library.

For information about how to provide a custom logger, see How to: Provide a Custom Logger.

For information related to regions, see the following topics:

For a complete list of How-to topics included with the Composite Application Guidance, see Development Activities.

Home page on MSDN | Community site