Skip to content

Commit

Permalink
delay region created and tracking of INavigationService
Browse files Browse the repository at this point in the history
  • Loading branch information
dansiegel committed Aug 10, 2020
1 parent 3c3460c commit c1fa5dd
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 7 deletions.
13 changes: 11 additions & 2 deletions e2e/Forms/src/HelloRegions/ViewModels/RegionAViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
namespace HelloRegions.ViewModels
using Prism.Navigation;
using Prism.Regions.Navigation;

namespace HelloRegions.ViewModels
{
public class RegionAViewModel : ViewModelBase
{
public RegionAViewModel()
public RegionAViewModel(INavigationService navigationService, IRegionNavigationService regionNavigation)
{
Title = "Hello from Region A";
NavigationService = navigationService;
RegionNavigation = regionNavigation;
}

public INavigationService NavigationService { get; set; }

public IRegionNavigationService RegionNavigation { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public static IContainerRegistry RegisterRegionServices(this IContainerRegistry
containerRegistry.Register<IRegionNavigationJournalEntry, RegionNavigationJournalEntry>();
containerRegistry.Register<IRegionNavigationJournal, RegionNavigationJournal>();
containerRegistry.Register<IRegionNavigationService, RegionNavigationService>();
containerRegistry.RegisterManySingleton<RegionResolverOverrides>(typeof(IResolverOverridesHelper), typeof(IActiveRegionHelper));
return containerRegistry.RegisterSingleton<IRegionManager, RegionManager>();
}

Expand Down
34 changes: 34 additions & 0 deletions src/Forms/Prism.Forms.Regions/Ioc/RegionResolverOverrides.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Text;
using Prism.Navigation;
using Prism.Regions;
using Prism.Regions.Navigation;

namespace Prism.Ioc
{
internal class RegionResolverOverrides : IResolverOverridesHelper, IActiveRegionHelper
{
public IRegion ActiveRegion { get; set; }

public IEnumerable<(Type Type, object Instance)> GetOverrides()
{
if (ActiveRegion == null)
{
return Array.Empty<(Type Type, object Instance)>();
}

var overrides = new List<(Type Type, object Instance)>
{
(typeof(IRegionNavigationService), ActiveRegion.NavigationService)
};

if (ActiveRegion is INavigationServiceAware nsa && nsa.NavigationService != null)
{
overrides.Add((typeof(INavigationService), nsa.NavigationService));
}

return overrides;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,13 @@ protected virtual IRegion CreateRegion(VisualElement targetElement, string regio
var regionAdapter = _regionAdapterMappings.GetMapping(targetElement.GetType());
var region = regionAdapter.Initialize(targetElement, regionName);
var cleanupBehavior = new RegionCleanupBehavior(region);
TargetElement.GetParentPage().Behaviors.Add(cleanupBehavior);
var page = targetElement.GetParentPage();
page.Behaviors.Add(cleanupBehavior);
if (region is INavigationServiceAware nsa)
{
nsa.NavigationService = Prism.Navigation.Xaml.Navigation.GetNavigationService(page);
}

return region;
}
catch (Exception ex)
Expand Down
7 changes: 7 additions & 0 deletions src/Forms/Prism.Forms.Regions/Regions/IActiveRegionHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Prism.Regions
{
internal interface IActiveRegionHelper
{
IRegion ActiveRegion { get; set; }
}
}
12 changes: 12 additions & 0 deletions src/Forms/Prism.Forms.Regions/Regions/INavigationServiceAware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
using Prism.Navigation;

namespace Prism.Regions
{
internal interface INavigationServiceAware
{
INavigationService NavigationService { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ public object LoadContent(IRegion region, INavigationContext navigationContext)
return view;
}

var activeRegion = _container.Resolve<IActiveRegionHelper>();
activeRegion.ActiveRegion = region;
view = CreateNewRegionItem(candidateTargetContract) as VisualElement;

activeRegion.ActiveRegion = null;
region.Add(view);

return view;
Expand Down
10 changes: 9 additions & 1 deletion src/Forms/Prism.Forms.Regions/Regions/Region.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq;
using Prism.Ioc;
using Prism.Mvvm;
using Prism.Navigation;
using Prism.Properties;
using Prism.Regions.Behaviors;
using Prism.Regions.Navigation;
Expand All @@ -14,7 +15,7 @@ namespace Prism.Regions
/// <summary>
/// Implementation of <see cref="IRegion"/> that allows multiple active views.
/// </summary>
public class Region : BindableBase, IRegion
public class Region : BindableBase, IRegion, INavigationServiceAware
{
private ObservableCollection<ItemMetadata> _itemMetadataCollection;
private IRegionManager _regionManager;
Expand All @@ -32,6 +33,13 @@ public Region()
_sort = DefaultSortComparison;
}

private WeakReference<INavigationService> _weakNavigationService;
INavigationService INavigationServiceAware.NavigationService
{
get => _weakNavigationService.TryGetTarget(out var target) ? target : null;
set => _weakNavigationService = new WeakReference<INavigationService>(value);
}

private ViewsCollection _views;
/// <summary>
/// Gets a readonly view of the collection of views in the region.
Expand Down
9 changes: 8 additions & 1 deletion src/Forms/Prism.Forms/Navigation/Xaml/Navigation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,14 @@ private static void OnNavigationScopeChanged(BindableObject bindable, object old
/// <param name="value">The Can Navigate value</param>
public static void SetCanNavigate(BindableObject view, bool value) => view.SetValue(CanNavigateProperty, value);

internal static INavigationService GetNavigationService(Page page)
/// <summary>
/// Gets the instance of <see cref="INavigationService"/> for the given <see cref="Page"/>
/// </summary>
/// <param name="page">The <see cref="Page"/></param>
/// <returns>The <see cref="INavigationService"/></returns>
/// <remarks>Do not use... this is an internal use API</remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
public static INavigationService GetNavigationService(Page page)
{
if(page == null) throw new ArgumentNullException(nameof(page));

Expand Down
4 changes: 3 additions & 1 deletion src/Forms/Prism.Forms/PrismApplicationBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ protected virtual void ConfigureViewModelLocator()
if(Container.IsRegistered<IResolverOverridesHelper>())
{
var resolver = Container.Resolve<IResolverOverridesHelper>();
overrides.AddRange(resolver.GetOverrides());
var resolverOverrides = resolver.GetOverrides();
if(resolverOverrides.Any())
overrides.AddRange(resolverOverrides);
}
if(!overrides.Any(x => x.Type == typeof(INavigationService)))
Expand Down

0 comments on commit c1fa5dd

Please sign in to comment.