Custom region adapter not working after upgrading to prism 4.0

Dec 5, 2011 at 2:43 PM
Edited Dec 5, 2011 at 2:51 PM

I am upgrading from composite application block to prism 4.0. My custom region adapters are not working. They are not getting added to the region manager. I have added the code snippet below. Any help greatly appreciated.

Thanks!

 

protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
      {
         RegionAdapterMappings mappings = base.ConfigureRegionAdapterMappings();
         mappings.RegisterMapping(typeof(Ribbon), new RibbonRegionAdapter());

         return mappings;
      }

 

   public sealed class RibbonRegionAdapter : IRegionAdapter
   {
      #region Fields
      private Ribbon _ribbon;
      #endregion
      
      #region IRegionAdapter Members
      /// <summary>
      /// Adapts a <see cref="Ribbon"/> and binds it to a new <see cref="IRegion"/>.
      /// </summary>
      /// <param name="regionTarget">The <see cref="Ribbon"/> to adapt</param>
      /// <param name="regionName"></param>
      /// <returns>The new <see cref="IRegion"/> that the <paramref name="regionTarget"/>is bound to.</returns>
      public IRegion Initialize(object regionTarget, string regionName)
      {
         _ribbon = regionTarget as Ribbon;
         IRegion region = null;
         if (_ribbon != null)
         {
            region = CreateRegion();
            region.Name = regionName;
            region.Views.CollectionChanged += Views_CollectionChanged;
         }
         return region;
      }

      void Views_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
      {
         if (e.Action == NotifyCollectionChangedAction.Add)
         {
            _ribbon.Tabs.AddRange(e.NewItems.Cast<Tab>().ToArray());
         }

      }

      #endregion
      /// <summary>
      /// Creates a new instance of <see cref="SingleActiveRegion"/>.
      /// </summary>
      /// <returns>A new instance of <see cref="SingleActiveRegion"/>.</returns>
      public IRegion CreateRegion()
      {
         return new SingleActiveRegion();
      }


   }
XAML code:
 <!-- Ribbon -->
      <ribbon:Ribbon x:Uid="ribbon:Ribbon_1"
                     cal:RegionManager.RegionName="{x:Static common:RegionNames.RibbonRegion}"
                     Grid.Row="0"
                     IsMinimized="True">

         <ribbon:Ribbon.ApplicationMenu>
            <ribbon:ApplicationMenu x:Uid="ribbon:ApplicationMenu_1" 
                                    cal:RegionManager.RegionName="{x:Static common:RegionNames.ApplicationMenuRegion}" 
                                    Width="125"/>
         </ribbon:Ribbon.ApplicationMenu>

      </ribbon:Ribbon>
Developer
Dec 5, 2011 at 5:51 PM
Edited Dec 5, 2011 at 5:52 PM

Hi,

Based on my understanding, it might be possible that this adapter is not working properly anymore due to the differences in the Prism 4 version. For example, this adapter implements the interface IRegionAdapter directly, however, in Prism v4, most region adapters inherit from the RegionAdapterBase<T> class (which implements the IRegionAdapter interface).

As far as I know, regions adapters for ribbon controls are not supported in Prism v4 as out of the box. However, you might find some code examples of ribbon region adapters for Prism v4 in third party sites that could be useful to achieve the requirements of your scenario.

Regards,

Damian Cherubini
http://blogs.southworks.net/dcherubini

Dec 5, 2011 at 6:30 PM

Thanks Damian,

I am experiencing the same problem even with StatusBar region adapters. And this adapter derives from RegionAdapterBase<StatusBar>.

Developer
Dec 5, 2011 at 6:44 PM

Hi,

It would be useful if you could provide us with a repro-sample application portraying the problems that you are mentioning, so we can help you find a possible solution for them (you could upload the repro-sample application, for example, to Skydrive)

Regards,

Damian Cherubini
http://blogs.southworks.net/dcherubini

Dec 5, 2011 at 8:12 PM

sorry i do not have a sample app, but i can post all the necessary code.

XAML code,
<!-- Status Bar -->
      <StatusBar x:Uid="StatusBar_1" 
                 cal:RegionManager.RegionName="{x:Static common:RegionNames.DashboardStatusBarRegion}"
                 Style="{StaticResource normalStatusBarStyle}"
                 Height="23"
                 Grid.Row="3" />
In the Bootstrapper,
protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
      {
         RegionAdapterMappings mappings = base.ConfigureRegionAdapterMappings();
         mappings.RegisterMapping(typeof(StatusBar), new StatusBarRegionAdapter(null));

         return mappings;
      }
The adapter,
/// <summary>
   /// Adapter that support status bar
   /// </summary>
   public sealed class StatusBarRegionAdapter : RegionAdapterBase<StatusBar>
   {
      /// <summary>
      /// 
      /// </summary>
      /// <param name="regionBehaviorFactory"></param>
      public StatusBarRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
         :base(regionBehaviorFactory)
      {
      }

      /// <summary>
      /// Adapts a <see cref="StatusBar"/> to a new <see cref="Region"/> 
      /// </summary>
      /// <param name="region"></param>
      /// <param name="regionTarget"></param>
      protected override void Adapt(IRegion region, StatusBar regionTarget)
      {
         if (regionTarget.ItemsSource != null)
         {
            throw new InvalidOperationException("StatusBar already has content");
         }
         region.Views.CollectionChanged += delegate
         {

            Object statusBar = region.Views.FirstOrDefault() as Object;
            regionTarget.Items.Add(statusBar);
         };
         
      }
      /// <summary>
      /// Creates a new instance of <see cref="SingleActiveRegion"/>
      /// </summary>
      /// <returns></returns>
      protected override IRegion CreateRegion()
      {
         return new SingleActiveRegion();
      }
   }

I do not have a IRegionBehaviorFactory, i am just passing null when creating a new instance of the adapter. What am i missing here?
Dec 5, 2011 at 8:57 PM
Edited Dec 6, 2011 at 5:17 PM

Hi Damian,

I managed to write a sample app. Here's the link,

https://skydrive.live.com/redir.aspx?cid=8c93dcbd9fcd8db1&resid=8C93DCBD9FCD8DB1!119&parid=8C93DCBD9FCD8DB1!117

If you run the app and add a breakpoint in the dashboardmodule's constructor, you'll see that the region for status bar is present in the regionmanager.

 

Thanks! 

Developer
Dec 6, 2011 at 4:09 PM

Hi,

You could try retrieving the instance of your StatusBarRegionAdapter in the ConfigureRegionAdapterMappings method of your SampleBootstrapper, using the container, this way the dependencies will be resolved automatically (e.g the IRegionBehaviorFactory which is needed by the RegionAdapterBase Class constructor). An example of this could be like in the following code snippet:

protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
      {
          RegionAdapterMappings mappings = base.ConfigureRegionAdapterMappings();
          mappings.RegisterMapping(typeof(StatusBar), this.Container.Resolve<StatusBarRegionAdapter>());

          return mappings;
      }

 
I tried this modification in your proposed sample, and your region "DashboardStatusBarRegion" was added to the RegionManager.

I hope you find this helpful

Agustin Adami
http://blogs.southworks.net/aadami


Dec 6, 2011 at 5:29 PM

Hi Agustin,

That helped, thanks a lot. I have got all my regions working except for the ApplicationMenu region in the ribbon. I am using an Actipro ribbon. The ApplicationMenu region is not being adde dto the region manager. I have updated my sample. Can you please let me know if i am missing something?

I have posted my sample in the link below,

https://skydrive.live.com/redir.aspx?cid=8c93dcbd9fcd8db1&resid=8C93DCBD9FCD8DB1!120&parid=8C93DCBD9FCD8DB1!117

 

Developer
Dec 7, 2011 at 6:05 PM

Hi,

We tried to reproduced the error you mentioned using the Microsoft Ribbon for WPF and the region was registered correctly in the RegionManager.

As this actipro ribbon control is a third party control and therefore, it might introduce some implementation differences, you might find better support in its official forums: actipro Support Forums.

Also, as mentioned before, take into account that regions adapters for ribbon controls are not supported in Prism v4 out of the box. You can find an existing work item created about this subject.

On the other hand the Prism Library provides three region adapters out-of-the-box that can be used as a reference.

You can find more information about this in the following chapters of the Prism documentation at MSDN:

Thanks,

Agustin Adami
http://blogs.southworks.net/aadami