RegionManager null in my custom RegionManager

Topics: Prism v4 - Silverlight 4
Oct 28, 2010 at 6:48 PM

I'm trying to put a region in a RadRibbon control.  One particular area is it's QuickAccessToolbar. 

The QATbar inherits from RadToolBar which inherits from ItemsControl so I would have though I wouldn't need to create a custom regionAdapter but since it's not working, I set out to do this.

The CreateRegion & Adapt functions are firing but still the region in my QATbar isn't showing up in RegionManager anywhere.

Setting a breakpoint in my Adapt method, the region object passed, RegionManager is set to null.

One thing I notice I had to do that differs from what you see in the docs is implement a constructor that takes in IRegionBehaviorFactory

My Custom RegionAdapter looks like this.

 public class QATBRegionAdapter : RegionAdapterBase<QuickAccessToolBar>        
    {

public QATBRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
            : base(regionBehaviorFactory)
        {

        }

        protected override void Adapt(IRegion region, QuickAccessToolBar regionTarget)
        {
            if (region == null) throw new ArgumentNullException("region");
            if (regionTarget == null) throw new ArgumentNullException("regionTarget");

            bool itemsSourceIsSet = regionTarget.ItemsSource != null;
#if !SILVERLIGHT
            itemsSourceIsSet = itemsSourceIsSet || (BindingOperations.GetBinding(regionTarget, ItemsControl.ItemsSourceProperty) != null);
#endif
            if (itemsSourceIsSet)
            {
                throw new InvalidOperationException("ItemsSource on QATB passed to QATBRegionAdapter is null.");
            }

            // If control has child items, move them to the region and then bind control to region. Can't set ItemsSource if child items exist.
            if (regionTarget.Items.Count > 0)
            {
                foreach (object childItem in regionTarget.Items)
                {
                    region.Add(childItem);
                }
                // Control must be empty before setting ItemsSource
                regionTarget.Items.Clear();
            }

            regionTarget.ItemsSource = region.Views;

        }

        protected override IRegion CreateRegion()
        {
            return new Region();
        }
    }
}

My questions are as follows.
The QuickAccessToolbar originates from ItemsControl so why would I need a regionadapter to start with.
Since I am trying to create a RegionAdapter to solve this problem, even though the my adapt and CreateRegion() methods are firing, why is my region still not showing up in the RegionManager?
Thanks.
Nov 1, 2010 at 2:51 AM

Ok, here's what I've had to do so far to get this to work.

RegionAdapter

private IRegionManager _regionManager;     

   [ImportingConstructor]
        public QATBRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory, IRegionManager regionManager)
            : base(regionBehaviorFactory)
        {
            _regionManager = regionManager;
        }

protected override void Adapt(IRegion region, QuickAccessToolBar regionTarget)
        {
            _instance = regionTarget;
            _instance.Items.Clear();

            if (region == null) throw new ArgumentNullException("region");
            if (regionTarget == null) throw new ArgumentNullException("regionTarget");

            bool itemsSourceIsSet = regionTarget.ItemsSource != null;
#if !SILVERLIGHT
            itemsSourceIsSet = itemsSourceIsSet || (BindingOperations.GetBinding(regionTarget, ItemsControl.ItemsSourceProperty) != null);
#endif
            if (itemsSourceIsSet)
            {
                throw new InvalidOperationException("ItemsSource on QATB passed to QATBRegionAdapter is null.");
            }

            // If control has child items, move them to the region and then bind control to region. Can't set ItemsSource if child items exist.
            if (regionTarget.Items.Count > 0)
            {
                foreach (object childItem in regionTarget.Items)
                {
                    region.Add(childItem);
                }
                // Control must be empty before setting ItemsSource
                regionTarget.Items.Clear();
            }

            regionTarget.ItemsSource = region.Views;

            _regionManager.Regions.Add(region);

        }

Bootstrapper:

protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
        {
            RegionAdapterMappings _mappings = base.ConfigureRegionAdapterMappings();
           
            _mappings.RegisterMapping(typeof(QuickAccessToolBar), this.Container.GetExportedValue<QATBRegionAdapter>());

            return _mappings;
        }

 

Nov 1, 2010 at 6:32 PM

Hi,

Nice to see that you solved your scenario and thanks for sharing it. Regarding to your question, if you have control that derives from ItemsControl, it would not be necessary to create a particular region adapter unless you find necessary to provide an specific behavior in the Adapt method or create a different region type.

Fernando Antivero

http://blogs.southworks.net/fantivero

Nov 1, 2010 at 6:45 PM

I found what I consider a workaround.  Why wouldn't the adapt automatically add the region for my adapter to RegionManager?

Also, you are correct, if I don't create a RegionAdapter I can use ViewDiscovery methods and items will show up in the region.

However, I mostly use ViewInjection.

If I use a ContentControl and put a region in it, it automatically gets added to RegionManager.

Again the control I'm using does derive from ItemsControl but again it's not showing up in RegionManager.

The sample for this can be found at http://www.dotnetpatterns.net/content/185-Silverlight-4.0-Prism-4.0-Telerik-Ribbon-Application-Template

Nov 1, 2010 at 10:34 PM

Hi,

As I said in your other forum thread, it is nice to see that you found a solution for this scenario. On the other hand, I checked in a simplified scenario (HelloWorld Quickstart) the creation of regions exposed in ApplicationMenu and in a QuicksAccessToolbar, and found not possible to add a view to these regions using View Injection.

There are not problems using View Discovery, as you mentioned. That said, your approach seems to be a possible solution in this scenario. If I found any other relevant information, I will post it here.

Fernando Antivero

http://blogs.southworks.net/fantivero