views navigation prism
Hey guys,
I'm using prism 4 to implement my presentation, the thing is that i'm using vi开发者_运维问答ew that contains region,now I want to navigate to other instance of the view under the same scope so I set the KeepAlive property of the view to false so that in navigation the view will be removed from the region and the new view will appear ,but I'm keep getting region name already exist exception. how can I navigate between few instances of the same view that contain region (only one should be in memory at the time) Thanks EranIt sounds like you want to use a scoped RegionManager with navigation. The reason you're seeing the region name already exists exception is because you have more than one region with the same name in the same RegionManager.
By default, PRISM doesn't support scoped RegionManagers with navigation, but it's pretty easy to add this in if you use custom RegionBehaviors. Essentially what you need to do is create an interface and then implement that interface on your view or view model. Then, create a RegionBehavior that looks for that interface and, if it meets the requirements, creates a new RegionManager instance for that view.
Here's what the interface might look like:
public interface IRegionScopeAware
{
bool IsRegionManagerScoped { get; }
}
And here's what the RegionBehavior might look like:
public class RegionScopeAwareBehavior : RegionBehavior
{
#region Overrides of RegionBehavior
protected override void OnAttach()
{
Region.Views.CollectionChanged += ViewsOnCollectionChanged;
ApplyScopedRegionManager(Region.Views.OfType<FrameworkElement>());
}
#endregion
private static void ViewsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems == null || e.Action != NotifyCollectionChangedAction.Add) return;
ApplyScopedRegionManager(e.NewItems.OfType<DependencyObject>());
}
private static void ApplyScopedRegionManager(IEnumerable<DependencyObject> views)
{
if (views == null) return;
foreach (var view in views)
{
ApplyScopedRegionManager(view);
}
}
private static void ApplyScopedRegionManager(DependencyObject view)
{
if (view == null) return;
IRegionScopeAware scopeAware = view as IRegionScopeAware;
if (scopeAware == null && view is FrameworkElement)
scopeAware = ((FrameworkElement) view).DataContext as IRegionScopeAware;
if (scopeAware != null)
ApplyScopedRegionManager(scopeAware, view);
}
private static void ApplyScopedRegionManager(IRegionScopeAware scopeAware, DependencyObject view)
{
if (view == null) return;
if (scopeAware == null) return;
if (scopeAware.IsRegionManagerScoped)
RegionManager.SetRegionManager(view, new RegionManager());
}
}
And don't forget that you'll need to register your RegionBehavior. I suggest registering it as a default RegionBehavior in the bootstrapper like so:
protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
{
IRegionBehaviorFactory factory = base.ConfigureDefaultRegionBehaviors();
factory.AddIfMissing(typeof(RegionScopeAwareBehavior).Name, typeof(RegionScopeAwareBehavior));
return factory;
}
精彩评论