Problem adding Regions to the RegionManager

Topics: Prism v4 - WPF 4
Mar 9, 2011 at 12:55 PM

Hi there,

We've run into a problem which I think may have something to do with WeakReferences being held when adding Regions to the RegionManager, and was wondering if anyone else had seen similar.

Occasionally, we are finding that our regions aren't available in the RegionManager. We have written a custom adapter for the DevExpress LayoutGroups and the Adapt method on that is not being called. We're using the UnityBootstrapper. We have two regions to be added.

Tracing it through, the call to RegionManager.UpdateRegions() which subsequently calls WeakDelegatesManager.Raise(). There are two listeners in the listeners collection, but both of their Targets are null, and are then removed from the listeners collection. This means that our Adapt method is never called and the regions aren't available. The xaml to configure the regions is this:

 

                        <dxdo:LayoutGroup Width="250" Orientation="Horizontal" cal:RegionManager.RegionName="PortfolioRegion" />
                        <dxdo:LayoutGroup cal:RegionManager.RegionName="MainRegion" />

 

I can force this to happen all the time by changing the following code in UnityBootstapper.cs:102 and adding a call to GC.Collect() :

                this.Logger.Log(Resources.SettingTheRegionManager, Category.Debug, Priority.Low);
                RegionManager.SetRegionManager(this.Shell, this.Container.Resolve<IRegionManager>());

                GC.Collect();

                this.Logger.Log(Resources.UpdatingRegions, Category.Debug, Priority.Low);
                RegionManager.UpdateRegions();

I can also prevent it happening by specializing DelayedRegionCreationBehavior to keep a reference to each DelayedRegionCreationBehavior. Or I can create a Unity LifetimeManager that keeps the reference. I can't use the ContainerControlledLifetimeManager as DelayedRegionCreationBehavior needs to be a unique instance as the TargetElements are different.

Can anyone suggest what I am doing wrong or whether it is expected behavior from Prism? Or if it isn't expected behavior, is there a fix for it?

Thanks.

Developer
Mar 9, 2011 at 6:31 PM

Hi,

I've tried adding the GC.Collect method in the line you've specified using the ItemsControlRegionAdapter, and I didn't experience the behavior you're mentioned. There is a strong reference to the DelayedRegionCreationBehavior in the event handler that is defined for the Loaded event of the target element. Therefore, if the target element is kept alive, the DelayedRegionCreationBehavior should also be kept alive (unless the UnWireTargetElement method has been called, since that method unregisters the aforementioned event handler).

If you can't find the reason why this is happening, it would be helpful if you could provide us with a repro sample so that we can help you further with this.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Mar 10, 2011 at 7:45 AM

Hi Guido,

Yes. That's it. The DevExpress LayoutGroups derive from ContentElement rather than FrameworkElement so do not have the Loaded event, no strong reference is being held and they are being collected.

Can you suggest a way to work around this? Is there a RegionCreationBehavior that can deal with ContentElement rather than FrameworkElements?

Thanks.

Developer
Mar 10, 2011 at 1:55 PM

Hi,

There's no region creation behavior made for ContentElement; however, you could create your own one that would listen for another event, or even create the region as soon as the behavior is attached.

You can find more information on Region Behaviors and how to create them in the following chapters from the Prism MSDN documentation:

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi