diff --git a/Toolkit.Avalonia/FrameHandler.cs b/Toolkit.Avalonia/FrameHandler.cs
index 97e0264..147a146 100644
--- a/Toolkit.Avalonia/FrameHandler.cs
+++ b/Toolkit.Avalonia/FrameHandler.cs
@@ -7,7 +7,7 @@ using Toolkit.UI.Controls.Avalonia;
namespace Toolkit.Avalonia;
-public class FrameHandler :
+public class FrameHandler(ITransientNavigationStore navigationStore) :
INotificationHandler>,
INotificationHandler>
{
@@ -18,19 +18,16 @@ public class FrameHandler :
frame.NavigationPageFactory ??= new NavigationPageFactory();
if (args.Template is Control control)
{
- void NavigatedTo(Control sender)
+ void Navigated(Control sender)
{
- async void HandleNavigatedTo(object? _,
- NavigationEventArgs __)
+ async void HandleNavigatedTo(object? _, NavigationEventArgs __)
{
- async void HandleNavigatingFrom(object? _,
- NavigatingCancelEventArgs args)
+ async void HandleNavigatingFrom(object? _, NavigatingCancelEventArgs args)
{
sender.RemoveHandler(Frame.NavigatingFromEvent, HandleNavigatingFrom);
control.Unloaded -= HandleUnloaded;
- async void HandleNavigatedFrom(object? _,
- NavigationEventArgs args)
+ async void HandleNavigatedFrom(object? _, NavigationEventArgs args)
{
sender.RemoveHandler(Frame.NavigatedFromEvent, HandleNavigatedFrom);
if (sender.DataContext is object content)
@@ -40,9 +37,11 @@ public class FrameHandler :
await deactivated.OnDeactivated();
}
- if (content is not IKeepAlive)
+ if (content is IDisposable disposable)
{
- if (content is IDisposable disposable)
+ FrameNavigationOptions? options = navigationStore.Get(frame);
+ if (options is not FrameNavigationOptions frameOptions ||
+ !frameOptions.IsNavigationStackEnabled)
{
disposable.Dispose();
}
@@ -51,9 +50,10 @@ public class FrameHandler :
}
sender.AddHandler(Frame.NavigatedFromEvent, HandleNavigatedFrom);
+
if (sender.DataContext is object content)
{
- if (content is IConfirmation confirmation &&
+ if (content is IConfirmation confirmation &&
!await confirmation.Confirm())
{
args.Cancel = true;
@@ -106,7 +106,6 @@ public class FrameHandler :
}
control.DataContext = args.Content;
- NavigatedTo(control);
FrameNavigationOptions navigationOptions = new();
List postNavigateActions = [];
@@ -133,31 +132,27 @@ public class FrameHandler :
if (args.Parameters is not null)
{
- if (args.Parameters.TryGetValue("Transition",
- out object? transition))
+ if (args.Parameters.TryGetValue("Transition", out object? transition))
{
switch ($"{transition}")
{
case "Suppress":
- navigationOptions.TransitionInfoOverride =
- new SuppressNavigationTransitionInfo();
+ navigationOptions.TransitionInfoOverride = new SuppressNavigationTransitionInfo();
break;
case "FromLeft":
case "FromRight":
case "FromTop":
case "FromBottom":
- navigationOptions.TransitionInfoOverride =
- new SlideNavigationTransitionInfo
- {
- Effect = Enum.Parse($"{transition}")
- };
+ navigationOptions.TransitionInfoOverride = new SlideNavigationTransitionInfo
+ {
+ Effect = Enum.Parse($"{transition}")
+ };
break;
}
}
- if (args.Parameters.TryGetValue("IsBackStackEnabled",
- out object? isBackStackEnabled))
+ if (args.Parameters.TryGetValue("IsBackStackEnabled", out object? isBackStackEnabled))
{
if (isBackStackEnabled is bool value)
{
@@ -165,8 +160,7 @@ public class FrameHandler :
}
}
- if (args.Parameters.TryGetValue("ClearBackStack",
- out object? clearBackStack))
+ if (args.Parameters.TryGetValue("ClearBackStack", out object? clearBackStack))
{
if (clearBackStack is bool clearBool)
{
@@ -178,8 +172,7 @@ public class FrameHandler :
if (clearBackStack is string clearString)
{
- if (clearString.StartsWith('[') && clearString.EndsWith(']') &&
- clearString.Contains('-'))
+ if (clearString.StartsWith('[') && clearString.EndsWith(']') && clearString.Contains('-'))
{
string range = clearString.Trim('[', ']');
string[] parts = range.Split('-');
@@ -202,6 +195,9 @@ public class FrameHandler :
}
}
+ Navigated(control);
+
+ navigationStore.Set(frame, navigationOptions);
frame.NavigateFromObject(control, navigationOptions);
foreach (Action postAction in postNavigateActions)
diff --git a/Toolkit.Avalonia/IServiceCollectionExtensions.cs b/Toolkit.Avalonia/IServiceCollectionExtensions.cs
index b3957c7..1f92754 100644
--- a/Toolkit.Avalonia/IServiceCollectionExtensions.cs
+++ b/Toolkit.Avalonia/IServiceCollectionExtensions.cs
@@ -33,7 +33,10 @@ public static class IServiceCollectionExtensions
services.AddHandler(nameof(IClassicDesktopStyleApplicationLifetime));
services.AddHandler(nameof(ISingleViewApplicationLifetime));
services.AddHandler(nameof(ContentControl));
+
services.AddHandler(nameof(Frame));
+ services.TryAddSingleton, TransientNavigationStore>();
+
services.AddHandler(nameof(ContentDialog));
services.AddHandler(nameof(TaskDialog));
@@ -66,7 +69,11 @@ public static class IServiceCollectionExtensions
services.AddHandler();
services.AddHandler(nameof(ContentControl));
+
services.AddHandler(nameof(Frame));
+
+ services.TryAddSingleton(provider.GetRequiredService>());
+
services.AddHandler(nameof(ContentDialog));
services.AddHandler(nameof(TaskDialog));
})));
diff --git a/Toolkit.Avalonia/ITransientNavigationStore.cs b/Toolkit.Avalonia/ITransientNavigationStore.cs
new file mode 100644
index 0000000..035db3c
--- /dev/null
+++ b/Toolkit.Avalonia/ITransientNavigationStore.cs
@@ -0,0 +1,15 @@
+namespace Toolkit.Avalonia;
+
+public interface ITransientNavigationStore
+ where TControl : class
+{
+ void Clear();
+
+ T? Get(TControl control)
+ where T : class;
+
+ void Remove(TControl control);
+
+ void Set(TControl control,
+ object parameters);
+}
\ No newline at end of file
diff --git a/Toolkit.Avalonia/TransientNavigationStore.cs b/Toolkit.Avalonia/TransientNavigationStore.cs
new file mode 100644
index 0000000..456f7be
--- /dev/null
+++ b/Toolkit.Avalonia/TransientNavigationStore.cs
@@ -0,0 +1,36 @@
+namespace Toolkit.Avalonia;
+
+public class TransientNavigationStore : ITransientNavigationStore
+ where TControl : class
+{
+ private readonly Dictionary> controlDataMap = [];
+
+ public void Set(TControl control,
+ object parameters)
+ {
+ if (!controlDataMap.TryGetValue(control, out var typeMap))
+ {
+ typeMap = new Dictionary();
+ controlDataMap[control] = typeMap;
+ }
+
+ typeMap[parameters.GetType()] = parameters;
+ }
+
+ public T? Get(TControl control)
+ where T : class
+ {
+ if (controlDataMap.TryGetValue(control, out var typeMap) &&
+ typeMap.TryGetValue(typeof(T), out var parameters))
+ {
+ typeMap.Remove(typeof(T));
+ return parameters as T;
+ }
+
+ return default;
+ }
+
+ public void Remove(TControl control) => controlDataMap.Remove(control);
+
+ public void Clear() => controlDataMap.Clear();
+}
diff --git a/Toolkit.Foundation/ContentFactory.cs b/Toolkit.Foundation/ContentFactory.cs
index e34b782..1b9d231 100644
--- a/Toolkit.Foundation/ContentFactory.cs
+++ b/Toolkit.Foundation/ContentFactory.cs
@@ -1,9 +1,10 @@
namespace Toolkit.Foundation;
public class ContentFactory(IServiceProvider provider,
- IServiceFactory factory) : IContentFactory
+ IServiceFactory factory) :
+ IContentFactory
{
- public Task