Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for DefaultView property #3250

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.ComponentModel;
using System.ComponentModel;
using Prism.Ioc;

namespace Prism.Navigation.Regions.Behaviors;
Expand Down Expand Up @@ -61,7 +61,7 @@ private void StartPopulatingContent()
var registration = registry.Registrations.FirstOrDefault(x => x.View == type);
if (registration is not null)
{
var view = registry.CreateView(container, registration.Name) as VisualElement;
var view = registry.CreateView(container, registration.Name);
Region.Add(view);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ protected override void Adapt(IRegion region, NavigationView regionTarget)
};
}

protected override IRegion CreateRegion()
protected override IRegion CreateRegion(object regionTarget)
{
return new SingleActiveRegion();
return new SingleActiveRegion(regionTarget);
}
}
2 changes: 1 addition & 1 deletion src/Wpf/Prism.Wpf/Navigation/Regions/AllActiveRegion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Prism.Navigation.Regions
/// <summary>
/// Region that keeps all the views in it as active. Deactivation of views is not allowed.
/// </summary>
public class AllActiveRegion : Region
public class AllActiveRegion(object target) : Region(target)
{
/// <summary>
/// Gets a readonly view of the collection of all the active views in the region. These are all the added views.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ private void StartPopulatingContent()
AddViewIntoRegion(view);
}

if (Region is ITargetAwareRegion targetAware && targetAware.Target is FrameworkElement target
&& target.GetValue(RegionManager.DefaultViewProperty) != null)
{
var defaultView = target.GetValue(RegionManager.DefaultViewProperty);
if (defaultView is string targetName)
Region.Add(targetName);
else if (defaultView is UIElement element)
Region.Add(element);
else if (defaultView is Type type)
{
var container = ContainerLocator.Container;
var view = container.Resolve(type);
Region.Add(view);
}
}

regionViewRegistry.ContentRegistered += OnViewRegistered;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ protected override void Adapt(IRegion region, ContentControl regionTarget)
/// Creates a new instance of <see cref="SingleActiveRegion"/>.
/// </summary>
/// <returns>A new instance of <see cref="SingleActiveRegion"/>.</returns>
protected override IRegion CreateRegion()
protected override IRegion CreateRegion(object regionTarget)
{
return new SingleActiveRegion();
return new SingleActiveRegion(regionTarget);
}
}
}
6 changes: 6 additions & 0 deletions src/Wpf/Prism.Wpf/Navigation/Regions/ITargetAwareRegion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Prism.Navigation.Regions;

public interface ITargetAwareRegion : IRegion
{
object Target { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ protected override void Adapt(IRegion region, ItemsControl regionTarget)
/// Creates a new instance of <see cref="AllActiveRegion"/>.
/// </summary>
/// <returns>A new instance of <see cref="AllActiveRegion"/>.</returns>
protected override IRegion CreateRegion()
protected override IRegion CreateRegion(object regionTarget)
{
return new AllActiveRegion();
return new AllActiveRegion(regionTarget);
}
}
}
11 changes: 9 additions & 2 deletions src/Wpf/Prism.Wpf/Navigation/Regions/Region.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Prism.Navigation.Regions
/// <summary>
/// Implementation of <see cref="IRegion"/> that allows multiple active views.
/// </summary>
public class Region : IRegion
public class Region : ITargetAwareRegion
{
private ObservableCollection<ItemMetadata> _itemMetadataCollection;
private string _name;
Expand All @@ -23,13 +23,20 @@ public class Region : IRegion
/// <summary>
/// Initializes a new instance of <see cref="Region"/>.
/// </summary>
public Region()
/// <param name="target">The target view of the Region</param>
public Region(object target)
{
Behaviors = new RegionBehaviorCollection(this);
Target = target;

_sort = DefaultSortComparison;
}

/// <summary>
/// Gets the target view of the Region.
/// </summary>
public object Target { get; }

/// <summary>
/// Occurs when a property value changes.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions src/Wpf/Prism.Wpf/Navigation/Regions/RegionAdapterBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public IRegion Initialize(T regionTarget, string regionName)
if (regionName == null)
throw new ArgumentNullException(nameof(regionName));

IRegion region = CreateRegion();
IRegion region = CreateRegion(regionTarget);
region.Name = regionName;

SetObservableRegionOnHostingControl(region, regionTarget);
Expand Down Expand Up @@ -121,7 +121,7 @@ protected virtual void AttachBehaviors(IRegion region, T regionTarget)
/// that will be used to adapt the object.
/// </summary>
/// <returns>A new instance of <see cref="IRegion"/>.</returns>
protected abstract IRegion CreateRegion();
protected abstract IRegion CreateRegion(object regionTarget);

private static T GetCastedObject(object regionTarget)
{
Expand Down
34 changes: 34 additions & 0 deletions src/Wpf/Prism.Wpf/Navigation/Regions/RegionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,40 @@ public static string GetRegionName(DependencyObject regionTarget)
return regionTarget.GetValue(RegionNameProperty) as string;
}

/// <summary>
/// Sets the DefaultView on the specified region
/// </summary>
public static readonly DependencyProperty DefaultViewProperty =
DependencyProperty.RegisterAttached("DefaultView", typeof(object), typeof(RegionManager), null);

/// <summary>
/// Gets the Default View Instance, Type or Name
/// </summary>
/// <param name="regionTarget">The Region Target View</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static object GetDefaultView(DependencyObject regionTarget)
{
if (regionTarget == null)
throw new ArgumentNullException(nameof(regionTarget));

return regionTarget.GetValue(DefaultViewProperty);
}

/// <summary>
/// Sets the Default Region View Instance, Type or Name.
/// </summary>
/// <param name="regionTarget">The Region Target.</param>
/// <param name="viewNameTypeOrInstance">The view instance, type or name.</param>
/// <exception cref="ArgumentNullException"></exception>
public static void SetDefaultView(DependencyObject regionTarget, object viewNameTypeOrInstance)
{
if (regionTarget == null)
throw new ArgumentNullException(nameof(regionTarget));

regionTarget.SetValue(DefaultViewProperty, viewNameTypeOrInstance);
}

private static readonly DependencyProperty ObservableRegionProperty =
DependencyProperty.RegisterAttached("ObservableRegion", typeof(ObservableObject<IRegion>), typeof(RegionManager), null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ protected override void AttachBehaviors(IRegion region, Selector regionTarget)
/// Creates a new instance of <see cref="Region"/>.
/// </summary>
/// <returns>A new instance of <see cref="Region"/>.</returns>
protected override IRegion CreateRegion()
protected override IRegion CreateRegion(object regionTarget)
{
return new Region();
return new Region(regionTarget);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ namespace Prism.Navigation.Regions
/// <summary>
/// Region that allows a maximum of one active view at a time.
/// </summary>
public class SingleActiveRegion : Region
public class SingleActiveRegion(object target) : Region(target)
{
/// <summary>
/// Marks the specified view as active.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using Prism.Ioc;
using Prism.IocContainer.Wpf.Tests.Support.Mocks.Views;
using Prism.Navigation.Regions;
Expand Down Expand Up @@ -31,7 +31,7 @@ public void ShouldFindCandidateViewInRegion()

// We cannot access the UnityRegionNavigationContentLoader directly so we need to call its
// GetCandidatesFromRegion method through a navigation request.
IRegion testRegion = new Region();
IRegion testRegion = new Region(new ContentControl());

MockView view = new MockView();
testRegion.Add(view);
Expand All @@ -54,7 +54,7 @@ public void ShouldFindCandidateViewWithFriendlyNameInRegion()

// We cannot access the Container specific RegionNavigationContentLoader directly so we need to call its
// GetCandidatesFromRegion method through a navigation request.
IRegion testRegion = new Region();
IRegion testRegion = new Region(new ContentControl());

var view = _container.Resolve<object>("SomeView") as MockView;
testRegion.Add(view);
Expand Down
4 changes: 2 additions & 2 deletions tests/Wpf/Prism.Wpf.Tests/Regions/AllActiveRegionFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class AllActiveRegionFixture
public void AddingViewsToRegionMarksThemAsActive()
{
ContainerLocator.SetContainerExtension(Mock.Of<IContainerExtension>());
IRegion region = new AllActiveRegion();
IRegion region = new AllActiveRegion(new ItemsControl());
var view = new object();

region.Add(view);
Expand All @@ -25,7 +25,7 @@ public void DeactivateThrows()
{
var ex = Assert.Throws<InvalidOperationException>(() =>
{
IRegion region = new AllActiveRegion();
IRegion region = new AllActiveRegion(new ItemsControl());
var view = new object();
region.Add(view);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public void WhenClearChildViewsPropertyIsNotSet_ThenChildViewsRegionManagerIsNot
{
var regionManager = new MockRegionManager();

var region = new Region();
var region = new Region(new ContentControl());
region.RegionManager = regionManager;

var behavior = new ClearChildViewsRegionBehavior();
Expand All @@ -37,7 +37,7 @@ public void WhenClearChildViewsPropertyIsTrue_ThenChildViewsRegionManagerIsClear
{
var regionManager = new MockRegionManager();

var region = new Region();
var region = new Region(new ContentControl());
region.RegionManager = regionManager;

var behavior = new ClearChildViewsRegionBehavior();
Expand All @@ -61,7 +61,7 @@ public void WhenRegionManagerChangesToNotNullValue_ThenChildViewsRegionManagerIs
{
var regionManager = new MockRegionManager();

var region = new Region();
var region = new Region(new ContentControl());
region.RegionManager = regionManager;

var behavior = new ClearChildViewsRegionBehavior();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public void DoesNotThrowWhenAddingNonActiveAwareDataContexts()
public void WhenParentViewGetsActivatedOrDeactivated_ThenChildViewIsNotUpdated()
{
var scopedRegionManager = new RegionManager();
var scopedRegion = new Region { Name = "MyScopedRegion", RegionManager = scopedRegionManager };
var scopedRegion = new Region(new ContentControl()) { Name = "MyScopedRegion", RegionManager = scopedRegionManager };
scopedRegionManager.Regions.Add(scopedRegion);
var behaviorForScopedRegion = new RegionActiveAwareBehavior { Region = scopedRegion };
behaviorForScopedRegion.Attach();
Expand Down Expand Up @@ -160,7 +160,7 @@ public void WhenParentViewGetsActivatedOrDeactivated_ThenChildViewIsNotUpdated()
public void WhenParentViewGetsActivatedOrDeactivated_ThenSyncedChildViewIsUpdated()
{
var scopedRegionManager = new RegionManager();
var scopedRegion = new Region { Name = "MyScopedRegion", RegionManager = scopedRegionManager };
var scopedRegion = new Region(new ContentControl()) { Name = "MyScopedRegion", RegionManager = scopedRegionManager };
scopedRegionManager.Regions.Add(scopedRegion);
var behaviorForScopedRegion = new RegionActiveAwareBehavior { Region = scopedRegion };
behaviorForScopedRegion.Attach();
Expand Down Expand Up @@ -189,7 +189,7 @@ public void WhenParentViewGetsActivatedOrDeactivated_ThenSyncedChildViewIsUpdate
public void WhenParentViewGetsActivatedOrDeactivated_ThenSyncedChildViewWithAttributeInVMIsUpdated()
{
var scopedRegionManager = new RegionManager();
var scopedRegion = new Region { Name = "MyScopedRegion", RegionManager = scopedRegionManager };
var scopedRegion = new Region(new ContentControl()) { Name = "MyScopedRegion", RegionManager = scopedRegionManager };
scopedRegionManager.Regions.Add(scopedRegion);
var behaviorForScopedRegion = new RegionActiveAwareBehavior { Region = scopedRegion };
behaviorForScopedRegion.Attach();
Expand Down Expand Up @@ -219,7 +219,7 @@ public void WhenParentViewGetsActivatedOrDeactivated_ThenSyncedChildViewWithAttr
public void WhenParentViewGetsActivatedOrDeactivated_ThenSyncedChildViewModelThatIsNotAFrameworkElementIsNotUpdated()
{
var scopedRegionManager = new RegionManager();
var scopedRegion = new Region { Name = "MyScopedRegion", RegionManager = scopedRegionManager };
var scopedRegion = new Region(new ContentControl()) { Name = "MyScopedRegion", RegionManager = scopedRegionManager };
scopedRegionManager.Regions.Add(scopedRegion);
var behaviorForScopedRegion = new RegionActiveAwareBehavior { Region = scopedRegion };
behaviorForScopedRegion.Attach();
Expand Down Expand Up @@ -248,7 +248,7 @@ public void WhenParentViewGetsActivatedOrDeactivated_ThenSyncedChildViewModelTha
public void WhenParentViewGetsActivatedOrDeactivated_ThenSyncedChildViewNotInActiveViewsIsNotUpdated()
{
var scopedRegionManager = new RegionManager();
var scopedRegion = new Region { Name = "MyScopedRegion", RegionManager = scopedRegionManager };
var scopedRegion = new Region(new ContentControl()) { Name = "MyScopedRegion", RegionManager = scopedRegionManager };
scopedRegionManager.Regions.Add(scopedRegion);
var behaviorForScopedRegion = new RegionActiveAwareBehavior { Region = scopedRegion };
behaviorForScopedRegion.Attach();
Expand Down Expand Up @@ -281,7 +281,7 @@ public void WhenParentViewGetsActivatedOrDeactivated_ThenSyncedChildViewNotInAct
public void WhenParentViewWithoutScopedRegionGetsActivatedOrDeactivated_ThenSyncedChildViewIsNotUpdated()
{
var commonRegionManager = new RegionManager();
var nonScopedRegion = new Region { Name = "MyRegion", RegionManager = commonRegionManager };
var nonScopedRegion = new Region(new ContentControl()) { Name = "MyRegion", RegionManager = commonRegionManager };
commonRegionManager.Regions.Add(nonScopedRegion);
var behaviorForScopedRegion = new RegionActiveAwareBehavior { Region = nonScopedRegion };
behaviorForScopedRegion.Attach();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ public RegionMemberLifetimeBehaviorFixture()

protected virtual void Arrange()
{
this.Region = new Region();
this.Behavior = new RegionMemberLifetimeBehavior();
this.Behavior.Region = this.Region;
this.Behavior.Attach();
Region = new Region(new ContentControl());
Behavior = new RegionMemberLifetimeBehavior();
Behavior.Region = Region;
Behavior.Attach();
}

[Fact]
Expand Down Expand Up @@ -257,10 +257,10 @@ public class RegionMemberLifetimeBehaviorAgainstSingleActiveRegionFixture
{
protected override void Arrange()
{
this.Region = new SingleActiveRegion();
this.Behavior = new RegionMemberLifetimeBehavior();
this.Behavior.Region = this.Region;
this.Behavior.Attach();
Region = new SingleActiveRegion(new ContentControl());
Behavior = new RegionMemberLifetimeBehavior();
Behavior.Region = Region;
Behavior.Attach();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ public void ShouldAllowMultipleSelectedItemsForListBox()

private SelectorItemsSourceSyncBehavior CreateBehavior()
{
Region region = new Region();
Region region = new Region(new ContentControl());
Selector selector = new TabControl();

var behavior = new SelectorItemsSourceSyncBehavior();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public TestableContentControlRegionAdapter() : base(null)

private MockPresentationRegion region = new MockPresentationRegion();

protected override IRegion CreateRegion()
protected override IRegion CreateRegion(object regionTarget)
{
return region;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public TestableItemsControlRegionAdapter() : base(null)

private MockPresentationRegion region = new MockPresentationRegion();

protected override IRegion CreateRegion()
protected override IRegion CreateRegion(object regionTarget)
{
return region;
}
Expand Down
Loading
Loading