• Memory Leak removing View with child regions in Prism-v2

    Published by on December 23rd, 2009 4:33 pm under Composite Application Guidance for WPF & SL, p&p, Patterns & Practices, Prism-v2, Prism-v2.1, Silverlight, Uncategorized, Windows Presentation Foundation, WPF

    2 Comments

    About a week ago in the Prism forum we got a question about an issue in the scenario displayed below.

    The Issue

    When the MainView was removed from the MainRegion, the RightOne and RightTwo regions were not removed from the RegionManager and the views were still being referenced by the region. We were able to reproduce this issue “successfully” both using scoped regions and without them so we started thinking on a possible fix for this.

    The Fix

    After trying different things out, we took Julian’s suggestions and created a RegionBehavior that would be in charge of this. You can find the complete code for this class below:

    public class ClearChildViewsRegionBehavior : RegionBehavior
       {
           public const string BehaviorKey = "ClearChildViews";
    
           protected override void OnAttach()
           {
               this.Region.PropertyChanged +=
                   new System.ComponentModel.PropertyChangedEventHandler(Region_PropertyChanged);
           }
    
           void Region_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
           {
               if (e.PropertyName == "RegionManager")
               {
                   if (this.Region.RegionManager == null)
                   {
                       foreach (object view in this.Region.Views)
                       {
                           DependencyObject dependencyObject = view as DependencyObject;
                           if (dependencyObject != null)
                           {
                               dependencyObject.ClearValue(RegionManager.RegionManagerProperty);
                           }
                       }
                   }
               }
           }
       }

    When the RegionManager property of a Region changes to null, the behavior removes the view’s RegionManager attached property of all views in the region. Adding this behavior by overriding the bootstrapper’s ConfigureDefaultRegionBehaviors will enable this behavior for all regions:

    protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
            {
                var regionBehaviorTypesDictionary = base.ConfigureDefaultRegionBehaviors();
                regionBehaviorTypesDictionary.AddIfMissing
                    (ClearChildViewsRegionBehavior.BehaviorKey, typeof(ClearChildViewsRegionBehavior));
                return regionBehaviorTypesDictionary;
            }

    The Outcome

    I have created a sample application showing how the fix works. You can download it from here. The code is provided “AS IS” with no warranties and confers no rights. I hope you can find this behavior useful if you have a similar kind of situation in your application.

    As I probably won’t blog anymore until after the holidays, have a merry Christmas and a happy new year :) .

    Shout it

    Tags: , , , , , , ,

    • Kashif Mujeeb

      I caught the same scenario, Thanks for the fix good work.

    • KrisPFJanssen

      Can this still be an issue in Prism 5?

Archives

Categories