« Prism loading dependent views » : différence entre les versions
De Banane Atomic
Aller à la navigationAller à la recherche
Aucun résumé des modifications |
|||
Ligne 88 : | Ligne 88 : | ||
public object View { get; set; } | public object View { get; set; } | ||
public string TargetRegionName { get; set; } | public string TargetRegionName { get; set; } | ||
} | |||
</filebox> | |||
= Views and ViewModels = | |||
<filebox fn='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> | |||
</filebox> | |||
<filebox fn='StepOneView.xaml.cs'> | |||
[DependentView(typeof(NextMenuItemView), "MenuRegion")] | |||
public partial class StepOneView | |||
{ } | |||
</filebox> | |||
<filebox fn='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"); | |||
} | |||
} | |||
</filebox> | |||
<filebox fn='StepTwoView.xaml.cs' collasped> | |||
[DependentView(typeof(PreviousMenuItemView), "MenuRegion")] | |||
[DependentView(typeof(NextMenuItemView), "MenuRegion")] | |||
public partial class StepTwoView | |||
{ } | |||
</filebox> | |||
<filebox fn='StepTwoViewModel.cs' collapsed> | |||
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"); | |||
} | |||
} | |||
</filebox> | |||
<filebox fn='StepThreeView.xaml.cs' collapsed> | |||
[DependentView(typeof(PreviousMenuItemView), "MenuRegion")] | |||
public partial class StepThreeView | |||
{ } | |||
</filebox> | |||
<filebox fn='StepThreeViewModel.cs' collapsed> | |||
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"); | |||
} | |||
} | } | ||
</filebox> | </filebox> |
Version du 27 octobre 2021 à 15:31
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; } } |
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"); } } |