« Prism loading dependent views » : différence entre les versions
De Banane Atomic
Aller à la navigationAller à la recherche
Aucun résumé des modifications |
|||
(Une version intermédiaire par le même utilisateur non affichée) | |||
Ligne 4 : | Ligne 4 : | ||
= Region behavior and Attribute = | = Region behavior and Attribute = | ||
Add a region behavior which create the dependent views and inject them into the target region. | |||
<filebox fn='DependentViewAttribute.cs'> | <filebox fn='DependentViewAttribute.cs'> | ||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] | ||
Ligne 19 : | Ligne 21 : | ||
</filebox> | </filebox> | ||
<filebox fn='DependentViewRegionBehavior.cs'> | <filebox fn='DependentViewRegionBehavior.cs' collapsed> | ||
public class DependentViewRegionBehavior : RegionBehavior | public class DependentViewRegionBehavior : RegionBehavior | ||
{ | { | ||
Ligne 88 : | Ligne 90 : | ||
public object View { get; set; } | public object View { get; set; } | ||
public string TargetRegionName { get; set; } | public string TargetRegionName { get; set; } | ||
} | |||
</filebox> | |||
<filebox fn='App.xaml.cs'> | |||
protected override void ConfigureDefaultRegionBehaviors(IRegionBehaviorFactory regionBehaviors) | |||
{ | |||
base.ConfigureDefaultRegionBehaviors(regionBehaviors); | |||
regionBehaviors.AddIfMissing(nameof(DependentViewRegionBehavior), typeof(DependentViewRegionBehavior)); | |||
} | } | ||
</filebox> | </filebox> |
Dernière version du 27 octobre 2021 à 15:33
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
Add a region behavior which create the dependent views and inject them into the target region.
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; } } |
App.xaml.cs |
protected override void ConfigureDefaultRegionBehaviors(IRegionBehaviorFactory regionBehaviors) { base.ConfigureDefaultRegionBehaviors(regionBehaviors); regionBehaviors.AddIfMissing(nameof(DependentViewRegionBehavior), typeof(DependentViewRegionBehavior)); } |
Views and ViewModels
MainWindow.xaml |
<Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Menu prism:RegionManager.RegionName="MenuRegion" /> <ContentControl Grid.Row="1" prism:RegionManager.RegionName="StepRegion" /> </Grid> |
StepOneView.xaml.cs |
[DependentView(typeof(NextMenuItemView), "MenuRegion")] public partial class StepOneView { } |
StepOneViewModel.cs |
public class StepOneViewModel : BindableBase { private readonly IRegionManager _regionManager; public ICommand GoToNextStepCommand { get; } public StepOneViewModel(IRegionManager regionManager) { _regionManager = regionManager; GoToNextStepCommand = new DelegateCommand(GoToNextStep); } private void GoToNextStep() { _regionManager.RequestNavigate("StepRegion", "StepTwoView"); } } |
StepTwoView.xaml.cs |
[DependentView(typeof(PreviousMenuItemView), "MenuRegion")] [DependentView(typeof(NextMenuItemView), "MenuRegion")] public partial class StepTwoView { } |
StepTwoViewModel.cs |
public class StepTwoViewModel : BindableBase { private readonly IRegionManager _regionManager; public ICommand GoToPreviousStepCommand { get; } public ICommand GoToNextStepCommand { get; } public StepTwoViewModel(IRegionManager regionManager) { _regionManager = regionManager; GoToPreviousStepCommand = new DelegateCommand(GoToPreviousStep); GoToNextStepCommand = new DelegateCommand(GoToNextStep); } private void GoToPreviousStep() { _regionManager.RequestNavigate("StepRegion", "StepOneView"); } private void GoToNextStep() { _regionManager.RequestNavigate("StepRegion", "StepThreeView"); } } |
StepThreeView.xaml.cs |
[DependentView(typeof(PreviousMenuItemView), "MenuRegion")] public partial class StepThreeView { } |
StepThreeViewModel.cs |
public class StepThreeViewModel : BindableBase { private readonly IRegionManager _regionManager; public ICommand GoToPreviousStepCommand { get; } public StepThreeViewModel(IRegionManager regionManager) { _regionManager = regionManager; GoToPreviousStepCommand = new DelegateCommand(GoToPreviousStep); } private void GoToPreviousStep() { _regionManager.RequestNavigate("StepRegion", "StepTwoView"); } } |