Prism loading dependent views
De Banane Atomic
Aller à la navigationAller à la recherche
Description
When a view is injected into a region, trigger the load of other views in other regions and pass them the same DataContext.
Region behavior and Attribute
DependentViewAttribute.cs |
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class DependentViewAttribute : Attribute { public Type Type { get; } public string TargetRegionName { get; } public DependentViewAttribute(Type viewType, string targetRegionName) { Type = viewType; TargetRegionName = targetRegionName; } } |
DependentViewRegionBehavior.cs |
public class DependentViewRegionBehavior : RegionBehavior { private readonly Dictionary<object, List<DependentViewInfo>> _dependentViewCache = new Dictionary<object, List<DependentViewInfo>>(); protected override void OnAttach() { Region.ActiveViews.CollectionChanged += ActiveViewsOnCollectionChanged; } private void ActiveViewsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Add) { foreach (var view in e.NewItems) { if (!_dependentViewCache.TryGetValue(view, out var viewInfoList)) { viewInfoList = new List<DependentViewInfo>(); foreach (var attribute in GetCustomAttribute<DependentViewAttribute>(view.GetType())) { var viewInfo = CreateDependentView(attribute); if (viewInfo.View is FrameworkElement viewToInject && view is FrameworkElement viewTrigger) { viewToInject.DataContext = viewTrigger.DataContext; } viewInfoList.Add(viewInfo); } if (!_dependentViewCache.ContainsKey(view)) { _dependentViewCache.Add(view, viewInfoList); } } viewInfoList.ForEach(x => Region.RegionManager.Regions[x.TargetRegionName].Add(x.View)); } } if (e.Action == NotifyCollectionChangedAction.Remove) { foreach (var view in e.OldItems) { if (_dependentViewCache.TryGetValue(view, out var viewInfoList)) { viewInfoList.ForEach(x => Region.RegionManager.Regions[x.TargetRegionName].Remove(x.View)); } } } } private DependentViewInfo CreateDependentView(DependentViewAttribute attribute) { return new DependentViewInfo { View = attribute.Type != null ? Activator.CreateInstance(attribute.Type) : null, TargetRegionName = attribute.TargetRegionName }; } private static IEnumerable<T> GetCustomAttribute<T>(Type type) => type.GetCustomAttributes(typeof(T), true).OfType<T>(); } internal class DependentViewInfo { public object View { get; set; } public string TargetRegionName { get; set; } } |