Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[UWP] Make Navigation and Transition overridable for NavigationPage #12439

Merged
merged 2 commits into from
Nov 26, 2020
Merged
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
@@ -0,0 +1,54 @@
using Windows.UI.Xaml.Media.Animation;
using Xamarin.Forms.ControlGallery.WindowsUniversal;
using Xamarin.Forms.Controls.Issues;
using Xamarin.Forms.Internals;
using Xamarin.Forms.Platform.UWP;

[assembly: ExportRenderer(typeof(NavPageOverrideUWP.CustomNavPageForOverride), typeof(NavPageOverrideRenderer))]
namespace Xamarin.Forms.ControlGallery.WindowsUniversal
{
public class NavPageOverrideRenderer : NavigationPageRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);

if (e.NewElement != null)
System.Diagnostics.Debug.WriteLine($"{e.NewElement.GetType()} is replaced by NavPageOverrideRenderer");
}

protected override void SetupPageTransition(Transition transition, bool isAnimated, bool isPopping)
{
var newTransition = new EntranceThemeTransition { FromVerticalOffset = 0};

if (isPopping)
{
newTransition.FromHorizontalOffset = -ContainerElement.ActualWidth;
}
else
{
newTransition.FromHorizontalOffset = ContainerElement.ActualWidth;
}

base.SetupPageTransition(newTransition, isAnimated, isPopping);
}

protected override void OnPushRequested(object sender, NavigationRequestedEventArgs e)
{
base.OnPushRequested(sender, e);
System.Diagnostics.Debug.WriteLine($"NavPageOverrideRenderer - OnPushRequested");
}

protected override void OnPopRequested(object sender, NavigationRequestedEventArgs e)
{
base.OnPopRequested(sender, e);
System.Diagnostics.Debug.WriteLine($"NavPageOverrideRenderer - OnPopRequested");
}

protected override void OnPopToRootRequested(object sender, NavigationRequestedEventArgs e)
{
base.OnPopToRootRequested(sender, e);
System.Diagnostics.Debug.WriteLine($"NavPageOverrideRenderer - OnPopToRootRequested");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
<Compile Include="BorderEffect.cs" />
<Compile Include="CustomSwitchRenderer.cs" />
<Compile Include="DisposePageRenderer.cs" />
<Compile Include="NavPageOverrideRenderer.cs" />
<Compile Include="PlatformSpecificCoreGalleryFactory.cs" />
<Compile Include="RegistrarValidationService.cs" />
<Compile Include="SampleNativeControl.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;

namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.None, 0, "NavigationPage override UWP push pop", PlatformAffected.UWP, NavigationBehavior.Default)]
public class NavPageOverrideUWP : ContentPage
{
public NavPageOverrideUWP()
{
var pushModalButton = new Button() { Text = "Open NavPage with overrides", BackgroundColor = Color.Blue, TextColor = Color.White};
pushModalButton.Clicked += (s, a) => Navigation.PushModalAsync(new CustomNavPageForOverride(new Page1()));

Content = new StackLayout{Children = { pushModalButton }};
}

public class Page1 : ContentPage
{
public Page1()
{
var pushButton = new Button() { Text = "Push with custom animation", BackgroundColor = Color.Blue, TextColor = Color.White};
pushButton.Clicked += (s, a) => Navigation.PushAsync(new Page2());

var popModalButton = new Button() { Text = "Pop modal", BackgroundColor = Color.Blue, TextColor = Color.White };
popModalButton.Clicked += (s, a) => Navigation.PopModalAsync();

Content = new StackLayout()
{
Padding = 40,
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center,
BackgroundColor = Color.Red,
Children = { pushButton, popModalButton }
};
}
}

public class Page2 : ContentPage
{
public Page2()
{
var popButton = new Button() { Text = "Pop with custom animation", BackgroundColor = Color.Blue, TextColor = Color.White, HeightRequest = 50};
popButton.Clicked += (s, a) => Navigation.PopAsync();

Content = new StackLayout
{
Padding = 40,
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center,
BackgroundColor = Color.Yellow,
Children = { popButton }
};
}
}


public class CustomNavPageForOverride : NavigationPage
{
public CustomNavPageForOverride(Page page) : base(page)
{

}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Issue9833.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue9929.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue9088.cs" />
<Compile Include="$(MSBuildThisFileDirectory)NavPageOverrideUWP.cs" />
<Compile Include="$(MSBuildThisFileDirectory)RefreshViewTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue7338.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ScrollToGroup.cs" />
Expand Down
37 changes: 24 additions & 13 deletions Xamarin.Forms.Platform.UAP/NavigationPageRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ protected void Dispose(bool disposing)
}
}

protected void OnElementChanged(VisualElementChangedEventArgs e)
protected virtual void OnElementChanged(VisualElementChangedEventArgs e)
{
EventHandler<VisualElementChangedEventArgs> changed = ElementChanged;
if (changed != null)
Expand Down Expand Up @@ -438,18 +438,18 @@ void OnPointerPressed(object sender, PointerRoutedEventArgs e)
}
}

void OnPopRequested(object sender, NavigationRequestedEventArgs e)
protected virtual void OnPopRequested(object sender, NavigationRequestedEventArgs e)
{
var newCurrent = Element.Peek(1);
SetPage(newCurrent, e.Animated, true);
}

void OnPopToRootRequested(object sender, NavigationRequestedEventArgs e)
protected virtual void OnPopToRootRequested(object sender, NavigationRequestedEventArgs e)
{
SetPage(e.Page, e.Animated, true);
}

void OnPushRequested(object sender, NavigationRequestedEventArgs e)
protected virtual void OnPushRequested(object sender, NavigationRequestedEventArgs e)
{
SetPage(e.Page, e.Animated, false);
}
Expand Down Expand Up @@ -500,19 +500,30 @@ void SetPage(Page page, bool isAnimated, bool isPopping)
UpdateTitleOnParents();
UpdateTitleView();

if (isAnimated && _transition == null)
SetupPageTransition(_transition, isAnimated, isPopping);

_container.Content = renderer.ContainerElement;
_container.DataContext = page;
}

protected virtual void SetupPageTransition(Transition transition, bool isAnimated, bool isPopping)
{
if (isAnimated && transition == null)
{
_transition = new EntranceThemeTransition();
transition = new EntranceThemeTransition();
_transition = (EntranceThemeTransition)transition;
_container.ContentTransitions = new TransitionCollection();
}

if (!isAnimated && _transition != null)
_container.ContentTransitions.Remove(_transition);
else if (isAnimated && _container.ContentTransitions.Count == 0)
_container.ContentTransitions.Add(_transition);

_container.Content = renderer.ContainerElement;
_container.DataContext = page;
if (!isAnimated && _container.ContentTransitions?.Count > 0)
{
_container.ContentTransitions.Clear();
}
else if (isAnimated && _container.ContentTransitions.Contains(transition) == false)
{
_container.ContentTransitions.Clear();
_container.ContentTransitions.Add(transition);
}
}

void UpdateBackButtonTitle()
Expand Down