Skip to content

Commit

Permalink
feat: Adding handlers for frame and page
Browse files Browse the repository at this point in the history
  • Loading branch information
nickrandolph committed Jul 10, 2023
1 parent 661b53b commit 25fe06f
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 2 deletions.
42 changes: 42 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/Frame/Frame.HotReload.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Reflection.Metadata;
using Uno.UI.Helpers;

[assembly: ElementMetadataUpdateHandlerAttribute(typeof(Windows.UI.Xaml.Controls.Frame), typeof(Windows.UI.Xaml.Controls.FrameElementMetadataUpdateHandler))]

namespace Windows.UI.Xaml.Controls
{
public partial class FrameElementMetadataUpdateHandler
{
public static void ElementUpdate(FrameworkElement element, Type[] updatedTypes)
{
var frame = element as Frame;
if (frame is null)
{
return;
}

foreach (var entry in frame.BackStack)
{
var expectedType = entry.SourcePageType.GetReplacementType();
if (entry.Instance is not null &&
entry.Instance.GetType() != expectedType)
{
var dc = entry.Instance.DataContext;
entry.Instance = Activator.CreateInstance(expectedType) as Page;
entry.Instance.Frame = frame;
if (entry.Instance is not null)
{
entry.Instance.DataContext = dc;
}
}

if (entry.SourcePageType is not null &&
entry.SourcePageType != expectedType)
{
entry.SourcePageType = expectedType;
}
}
}
}
}
13 changes: 11 additions & 2 deletions src/Uno.UI/UI/Xaml/Controls/Frame/Frame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using System.Runtime.CompilerServices;
using Windows.UI.Xaml.Input;
using Uno.UI.Xaml.Core;
using Uno.UI.Helpers;

namespace Windows.UI.Xaml.Controls
{
Expand Down Expand Up @@ -55,6 +56,13 @@ protected override void OnContentChanged(object oldValue, object newValue)
{
CurrentEntry = null;
}
else if (CurrentEntry is not null)
{
// This is to support hot reload scenarios - the PageStackEntry
// is used when navigating back to this page as it's maintained in the BackStack
CurrentEntry.Instance = newValue as Page;
CurrentEntry.SourcePageType = newValue.GetType();
}
}

#region BackStackDepth DependencyProperty
Expand Down Expand Up @@ -272,7 +280,7 @@ public void GoForward()

public bool Navigate(Type sourcePageType, object parameter, NavigationTransitionInfo infoOverride)
{
var entry = new PageStackEntry(sourcePageType, parameter, infoOverride);
var entry = new PageStackEntry(sourcePageType.GetReplacementType(), parameter, infoOverride);
return InnerNavigate(entry, NavigationMode.New);
}

Expand Down Expand Up @@ -432,7 +440,8 @@ private void ReleasePages(IList<PageStackEntry> pageStackEntries)

internal Page EnsurePageInitialized(PageStackEntry entry)
{
if (entry is { Instance: null } && CreatePageInstanceCached(entry.SourcePageType) is { } page)
if (entry is { Instance: null } &&
CreatePageInstanceCached(entry.SourcePageType) is { } page)
{
page.Frame = this;
entry.Instance = page;
Expand Down
25 changes: 25 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/Page/Page.HotReload.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Reflection.Metadata;
using Uno.UI.Helpers;

[assembly: ElementMetadataUpdateHandlerAttribute(typeof(Windows.UI.Xaml.Controls.Page), typeof(Windows.UI.Xaml.Controls.PageElementMetadataUpdateHandler))]

namespace Windows.UI.Xaml.Controls
{
public partial class PageElementMetadataUpdateHandler
{
public static void AfterElementReplaced(FrameworkElement oldView, FrameworkElement newView, Type[] updatedTypes)
{
if (oldView is Page oldPage &&
newView is Page newPage)
{
newPage.Frame = oldPage.Frame;

// If we've replaced the Page in its frame, we may need to
// swap the content property as well. If may be required
// if the frame is handled by a (native) FramePresenter.
newPage.Frame.Content = newPage;
}
}
}
}

0 comments on commit 25fe06f

Please sign in to comment.