Prism 4 - locally scoped RegionManager

前端 未结 2 561
半阙折子戏
半阙折子戏 2021-02-09 19:07

I have silverlight 4 application with PRISM 4, I\'m using MEF.

My Shell defines one main region in which modules are loaded, I want modules to have their own RegionManag

相关标签:
2条回答
  • 2021-02-09 19:42

    I was in the same situation as you, I had a nested region manager, but all of the child views were still getting the global region manager. I came up with what I consider a reasonable solution.

    First I define an interface:

    /// <summary>
    /// An interface which is aware of the current region manager.
    /// </summary>
    public interface IRegionManagerAware
    {
        /// <summary>
        /// Gets or sets the current region manager.
        /// </summary>
        /// <value>
        /// The current region manager.
        /// </value>
        IRegionManager RegionManager { get; set; }
    }
    

    Then I setup a RegionBehavior like so:

    /// <summary>
    /// A behaviour class which attaches the current scoped <see cref="IRegionManager"/> to views and their data contexts.
    /// </summary>
    public class RegionAwareBehaviour : RegionBehavior
    {
        /// <summary>
        /// The key to identify this behaviour.
        /// </summary>
        public const string RegionAwareBehaviourKey = "RegionAwareBehaviour";
    
        /// <summary>
        /// Override this method to perform the logic after the behaviour has been attached.
        /// </summary>
        protected override void OnAttach()
        {
            Region.Views.CollectionChanged += RegionViewsChanged;
        }
    
        private void RegionViewsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            Contract.Requires<ArgumentNullException>(e != null);
    
            if (e.NewItems != null)
                foreach (var item in e.NewItems)
                    MakeViewAware(item);
        }
    
        private void MakeViewAware(object view)
        {
            Contract.Requires<ArgumentNullException>(view != null);
    
            var frameworkElement = view as FrameworkElement;
            if (frameworkElement != null)
                MakeDataContextAware(frameworkElement);
    
            MakeAware(view);
        }
    
        private void MakeDataContextAware(FrameworkElement frameworkElement)
        {
            Contract.Requires<ArgumentNullException>(frameworkElement != null);
    
            if (frameworkElement.DataContext != null)
                MakeAware(frameworkElement.DataContext);
        }
    
        private void MakeAware(object target)
        {
            Contract.Requires<ArgumentNullException>(target != null);
    
            var scope = target as IRegionManagerAware;
            if (scope != null)
                scope.RegionManager = Region.RegionManager;
        }
    }
    

    Then apply this to all regions in your bootstrapper:

    protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
    {
        var behaviours = base.ConfigureDefaultRegionBehaviors();
    
        behaviours.AddIfMissing(RegionAwareBehaviour.RegionAwareBehaviourKey, typeof(RegionAwareBehaviour));
    
        return behaviours;
    }
    

    Then all you have to do is implement IRegionManagerAware on your view/viewmodel, probably like so:

    public class MyView : IRegionManagerAware
    {
        IRegionManager RegionManager { set; get; }
    }
    

    Then when this view is added to a region, the behaviour will correctly set the RegionManager property to the currently scoped region manager.

    0 讨论(0)
  • 2021-02-09 19:53

    If you read the next line in the documentation it says "The Add method will return the new RegionManager that the view can retain for further access to the local scope."

    so I would create a property in the view and pass the IRegionManger to it.

    inside your view/viewModel.

    public IRegionManager rm { get; set; }
    

    then pass the IregionManager which was returned after adding the new view

    view.rm = detailsRegionManager;
    

    Hope that helps.

    0 讨论(0)
提交回复
热议问题