Skip to content
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
40 changes: 23 additions & 17 deletions samples/Sample.Avalonia/Views/DView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
xmlns:an="https://github.com/NeverMorewd/AsyncNavigation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:Sample.Common"
xmlns:vm="using:Sample.Common"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d"
x:DataType="vm:DViewModel">
x:DataType="vm:DViewModel"
mc:Ignorable="d">
<DockPanel LastChildFill="True">
<StackPanel DockPanel.Dock="Left" Orientation="Vertical">
<StackPanel Spacing="4" Orientation="Horizontal">
<Button Classes="GoBack"/>
<Button Classes="GoForward"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="4">
<Button Classes="GoBack" />
<Button Classes="GoForward" />
</StackPanel>
<Button
Classes="Navigation"
Content="ToA"
Expand All @@ -24,7 +24,7 @@
Classes="Navigation"
Content="ToE"
Tag="EView" />
<Button
<Button
Classes="Navigation"
Content="ToE:Delay"
Tag="EView:Delay" />
Expand All @@ -36,17 +36,18 @@
Classes="Navigation"
Content="ToE:New;Delay"
Tag="EView:New;Delay" />
<Button
Classes="NavigationAndForget"
Content="ToA:Forget"
Tag="AView" />
<Button
Classes="NavigationAndForget"
Content="ToA:Forget;New"
Tag="AView:New" />
<Button
Classes="NavigationAndForget"
Content="ToA:Forget"
Tag="AView" />
<Button
Classes="NavigationAndForget"
Content="ToA:Forget;New"
Tag="AView:New" />
</StackPanel>
<ScrollViewer>
<TabControl
Name="tab"
an:RegionManager.PreferCache="True"
an:RegionManager.RegionName="TabRegion"
TabStripPlacement="Top">
Expand All @@ -57,7 +58,12 @@
Orientation="Horizontal"
Spacing="4">
<TextBlock VerticalAlignment="Center" Text="{ReflectionBinding ViewName}" />
<Button Margin="10" Content="x" />
<Button
Margin="10"
Command="{ReflectionBinding DataContext.RequestUnloadViewCommand,
ElementName=tab}"
CommandParameter="{Binding}"
Content="x" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
Expand Down
2 changes: 1 addition & 1 deletion samples/Sample.Common/AViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public AViewModel(IRegionManager regionManager)
[ReactiveCommand]
private Task UnloadView(string param)
{
return RequestUnloadAsync();
return RequestUnloadAsync(CancellationToken.None);
}

[ReactiveCommand]
Expand Down
2 changes: 1 addition & 1 deletion samples/Sample.Common/BViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ private Task AsyncNavigateAndForget(string param)
[ReactiveCommand]
private Task UnloadView(string param)
{
return RequestUnloadAsync();
return RequestUnloadAsync(CancellationToken.None);
}
public override async Task OnNavigatedToAsync(NavigationContext context)
{
Expand Down
2 changes: 1 addition & 1 deletion samples/Sample.Common/CViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ private async Task AsyncNavigate(string param)
[ReactiveCommand]
private Task UnloadView(string param)
{
return RequestUnloadAsync();
return RequestUnloadAsync(CancellationToken.None);
}
}
14 changes: 13 additions & 1 deletion samples/Sample.Common/DViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using AsyncNavigation.Abstractions;
using AsyncNavigation;
using AsyncNavigation.Abstractions;
using AsyncNavigation.Core;
using ReactiveUI.SourceGenerators;
namespace Sample.Common;
Expand Down Expand Up @@ -35,4 +36,15 @@ private async Task GoBack()
{
await _regionManager.GoBack("TabRegion");
}
[ReactiveCommand]
private async Task RequestUnloadView(NavigationContext navigationContext)
{
if (navigationContext.TryResolveNavigationAware(out var aware))
{
if (aware is ViewModelBase viewModel)
{
await viewModel.RequestUnloadAsync(CancellationToken.None);
}
}
}
}
2 changes: 1 addition & 1 deletion samples/Sample.Common/EViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public ObservableCollection<byte> HeavyItems
[ReactiveCommand]
private Task UnloadView(string param)
{
return RequestUnloadAsync();
return RequestUnloadAsync(CancellationToken.None);
}

[ReactiveCommand]
Expand Down
2 changes: 1 addition & 1 deletion samples/Sample.Common/ViewModelBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public virtual Task OnUnloadAsync(CancellationToken cancellationToken)
return Task.CompletedTask;
}

protected Task RequestUnloadAsync()
public Task RequestUnloadAsync(CancellationToken cancellationToken)
{
if (AsyncRequestUnloadEvent == null)
{
Expand Down
7 changes: 6 additions & 1 deletion samples/Sample.Wpf/Views/DView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,19 @@
</StackPanel>
<ScrollViewer>
<TabControl
x:Name="tab"
an:RegionManager.PreferCache="True"
an:RegionManager.RegionName="TabRegion"
TabStripPlacement="Top">
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="2" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="{Binding ViewName}" />
<Button Margin="10" Content="x" />
<Button
Margin="10"
Command="{Binding DataContext.RequestUnloadViewCommand, ElementName=tab}"
CommandParameter="{Binding}"
Content="x" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
Expand Down
21 changes: 0 additions & 21 deletions src/AsyncNavigation/CoreExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,25 +113,4 @@ public static void DisposeAll(this IEnumerable<IDisposable> disposables)
disposable.Dispose();
}
}

public static NavigationContext WithParameter(this NavigationContext navigationContext, string key, object value)
{
if (navigationContext.IsCompleted && !navigationContext.IsForwordNavigation && !navigationContext.IsBackNavigation)
throw new InvalidOperationException("Cannot add parameters after navigation is completed.");

navigationContext.Parameters ??= new NavigationParameters();
navigationContext.Parameters.Add(key, value);
return navigationContext;
}

public static NavigationContext WithParameters(this NavigationContext navigationContext, IEnumerable<KeyValuePair<string, object>> parameters)
{

if (navigationContext.IsCompleted && !navigationContext.IsForwordNavigation && !navigationContext.IsBackNavigation)
throw new InvalidOperationException("Cannot add parameters after navigation is completed.");

navigationContext.Parameters ??= new NavigationParameters();
navigationContext.Parameters.AddRange(parameters);
return navigationContext;
}
}
79 changes: 79 additions & 0 deletions src/AsyncNavigation/NavigationContextExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using AsyncNavigation.Abstractions;
using AsyncNavigation.Core;
using System.Diagnostics.CodeAnalysis;

namespace AsyncNavigation;

public static class NavigationContextExtensions
{
public static bool TryResolveView(this NavigationContext navigationContext, [MaybeNullWhen(false)] out IView view)
{
if (navigationContext.Target.IsSet)
{
view = navigationContext.Target.Value!;
return true;
}
view = default;
return false;
}

public static bool TryResolveNavigationAware(this NavigationContext navigationContext, [MaybeNullWhen(false)] out INavigationAware aware)
{
if (navigationContext.Target.IsSet)
{
if(navigationContext.Target.Value is not null
&& navigationContext.Target.Value.DataContext is INavigationAware navAware)
{
aware = navAware;
return true;
}
}
aware = default;
return false;
}

public static bool TryResolveViewAndAware(this NavigationContext navigationContext,
[MaybeNullWhen(false)] out IView view,
[MaybeNullWhen(false)] out INavigationAware aware)
{
view = default;
aware = default;

if (!navigationContext.Target.IsSet)
return false;

var target = navigationContext.Target.Value;
if (target is null)
return false;

view = target;

if (target.DataContext is INavigationAware navAware)
{
aware = navAware;
return true;
}
return false;
}
public static NavigationContext WithParameter(this NavigationContext navigationContext, string key, object value)
{
if (navigationContext.IsCompleted && !navigationContext.IsForwordNavigation && !navigationContext.IsBackNavigation)
throw new InvalidOperationException("Cannot add parameters after navigation is completed.");

navigationContext.Parameters ??= new NavigationParameters();
navigationContext.Parameters.Add(key, value);
return navigationContext;
}

public static NavigationContext WithParameters(this NavigationContext navigationContext, IEnumerable<KeyValuePair<string, object>> parameters)
{

if (navigationContext.IsCompleted && !navigationContext.IsForwordNavigation && !navigationContext.IsBackNavigation)
throw new InvalidOperationException("Cannot add parameters after navigation is completed.");

navigationContext.Parameters ??= new NavigationParameters();
navigationContext.Parameters.AddRange(parameters);
return navigationContext;
}

}
8 changes: 1 addition & 7 deletions src/AsyncNavigation/RegionNavigationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,19 +138,13 @@ private async Task OnBeforeNavigationAsync(NavigationContext navigationContext)
{
var currentAware = (Current.Value.View.DataContext as INavigationAware)!;
await currentAware.OnNavigatedFromAsync(navigationContext);
// todo: why detach?
//if (_regionPresenter.IsSinglePageRegion)
//{
// _unloadHandler.Detach(currentAware);
//}
}
navigationContext.CancellationToken.ThrowIfCancellationRequested();
}

private async Task OnAfterNavigationAsync(NavigationContext navigationContext)
{
if (navigationContext.Target.Value is IView view
&& view.DataContext is INavigationAware aware)
if (navigationContext.TryResolveViewAndAware(out var view,out var aware))
{
var contextSnapshot = navigationContext;
WeakUnloadObserver.Subscribe(aware, a =>
Expand Down
Loading