Skip to content

Commit be3ede9

Browse files
authored
NavigationContextExtensions (#32)
add requestunloadviewcommand for tabregion sample
1 parent 39b7b45 commit be3ede9

11 files changed

Lines changed: 127 additions & 52 deletions

File tree

samples/Sample.Avalonia/Views/DView.axaml

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
xmlns:an="https://github.com/NeverMorewd/AsyncNavigation"
66
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
77
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8-
xmlns:vm="using:Sample.Common"
8+
xmlns:vm="using:Sample.Common"
99
d:DesignHeight="450"
1010
d:DesignWidth="800"
11-
mc:Ignorable="d"
12-
x:DataType="vm:DViewModel">
11+
x:DataType="vm:DViewModel"
12+
mc:Ignorable="d">
1313
<DockPanel LastChildFill="True">
1414
<StackPanel DockPanel.Dock="Left" Orientation="Vertical">
15-
<StackPanel Spacing="4" Orientation="Horizontal">
16-
<Button Classes="GoBack"/>
17-
<Button Classes="GoForward"/>
18-
</StackPanel>
15+
<StackPanel Orientation="Horizontal" Spacing="4">
16+
<Button Classes="GoBack" />
17+
<Button Classes="GoForward" />
18+
</StackPanel>
1919
<Button
2020
Classes="Navigation"
2121
Content="ToA"
@@ -24,7 +24,7 @@
2424
Classes="Navigation"
2525
Content="ToE"
2626
Tag="EView" />
27-
<Button
27+
<Button
2828
Classes="Navigation"
2929
Content="ToE:Delay"
3030
Tag="EView:Delay" />
@@ -36,17 +36,18 @@
3636
Classes="Navigation"
3737
Content="ToE:New;Delay"
3838
Tag="EView:New;Delay" />
39-
<Button
40-
Classes="NavigationAndForget"
41-
Content="ToA:Forget"
42-
Tag="AView" />
43-
<Button
44-
Classes="NavigationAndForget"
45-
Content="ToA:Forget;New"
46-
Tag="AView:New" />
39+
<Button
40+
Classes="NavigationAndForget"
41+
Content="ToA:Forget"
42+
Tag="AView" />
43+
<Button
44+
Classes="NavigationAndForget"
45+
Content="ToA:Forget;New"
46+
Tag="AView:New" />
4747
</StackPanel>
4848
<ScrollViewer>
4949
<TabControl
50+
Name="tab"
5051
an:RegionManager.PreferCache="True"
5152
an:RegionManager.RegionName="TabRegion"
5253
TabStripPlacement="Top">
@@ -57,7 +58,12 @@
5758
Orientation="Horizontal"
5859
Spacing="4">
5960
<TextBlock VerticalAlignment="Center" Text="{ReflectionBinding ViewName}" />
60-
<Button Margin="10" Content="x" />
61+
<Button
62+
Margin="10"
63+
Command="{ReflectionBinding DataContext.RequestUnloadViewCommand,
64+
ElementName=tab}"
65+
CommandParameter="{Binding}"
66+
Content="x" />
6167
</StackPanel>
6268
</DataTemplate>
6369
</TabControl.ItemTemplate>

samples/Sample.Common/AViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public AViewModel(IRegionManager regionManager)
2121
[ReactiveCommand]
2222
private Task UnloadView(string param)
2323
{
24-
return RequestUnloadAsync();
24+
return RequestUnloadAsync(CancellationToken.None);
2525
}
2626

2727
[ReactiveCommand]

samples/Sample.Common/BViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ private Task AsyncNavigateAndForget(string param)
3434
[ReactiveCommand]
3535
private Task UnloadView(string param)
3636
{
37-
return RequestUnloadAsync();
37+
return RequestUnloadAsync(CancellationToken.None);
3838
}
3939
public override async Task OnNavigatedToAsync(NavigationContext context)
4040
{

samples/Sample.Common/CViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ private async Task AsyncNavigate(string param)
2020
[ReactiveCommand]
2121
private Task UnloadView(string param)
2222
{
23-
return RequestUnloadAsync();
23+
return RequestUnloadAsync(CancellationToken.None);
2424
}
2525
}

samples/Sample.Common/DViewModel.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using AsyncNavigation.Abstractions;
1+
using AsyncNavigation;
2+
using AsyncNavigation.Abstractions;
23
using AsyncNavigation.Core;
34
using ReactiveUI.SourceGenerators;
45
namespace Sample.Common;
@@ -35,4 +36,15 @@ private async Task GoBack()
3536
{
3637
await _regionManager.GoBack("TabRegion");
3738
}
39+
[ReactiveCommand]
40+
private async Task RequestUnloadView(NavigationContext navigationContext)
41+
{
42+
if (navigationContext.TryResolveNavigationAware(out var aware))
43+
{
44+
if (aware is ViewModelBase viewModel)
45+
{
46+
await viewModel.RequestUnloadAsync(CancellationToken.None);
47+
}
48+
}
49+
}
3850
}

samples/Sample.Common/EViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public ObservableCollection<byte> HeavyItems
2020
[ReactiveCommand]
2121
private Task UnloadView(string param)
2222
{
23-
return RequestUnloadAsync();
23+
return RequestUnloadAsync(CancellationToken.None);
2424
}
2525

2626
[ReactiveCommand]

samples/Sample.Common/ViewModelBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public virtual Task OnUnloadAsync(CancellationToken cancellationToken)
6262
return Task.CompletedTask;
6363
}
6464

65-
protected Task RequestUnloadAsync()
65+
public Task RequestUnloadAsync(CancellationToken cancellationToken)
6666
{
6767
if (AsyncRequestUnloadEvent == null)
6868
{

samples/Sample.Wpf/Views/DView.xaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,19 @@
4646
</StackPanel>
4747
<ScrollViewer>
4848
<TabControl
49+
x:Name="tab"
4950
an:RegionManager.PreferCache="True"
5051
an:RegionManager.RegionName="TabRegion"
5152
TabStripPlacement="Top">
5253
<TabControl.ItemTemplate>
5354
<DataTemplate>
5455
<StackPanel Margin="2" Orientation="Horizontal">
5556
<TextBlock VerticalAlignment="Center" Text="{Binding ViewName}" />
56-
<Button Margin="10" Content="x" />
57+
<Button
58+
Margin="10"
59+
Command="{Binding DataContext.RequestUnloadViewCommand, ElementName=tab}"
60+
CommandParameter="{Binding}"
61+
Content="x" />
5762
</StackPanel>
5863
</DataTemplate>
5964
</TabControl.ItemTemplate>

src/AsyncNavigation/CoreExtensions.cs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -113,25 +113,4 @@ public static void DisposeAll(this IEnumerable<IDisposable> disposables)
113113
disposable.Dispose();
114114
}
115115
}
116-
117-
public static NavigationContext WithParameter(this NavigationContext navigationContext, string key, object value)
118-
{
119-
if (navigationContext.IsCompleted && !navigationContext.IsForwordNavigation && !navigationContext.IsBackNavigation)
120-
throw new InvalidOperationException("Cannot add parameters after navigation is completed.");
121-
122-
navigationContext.Parameters ??= new NavigationParameters();
123-
navigationContext.Parameters.Add(key, value);
124-
return navigationContext;
125-
}
126-
127-
public static NavigationContext WithParameters(this NavigationContext navigationContext, IEnumerable<KeyValuePair<string, object>> parameters)
128-
{
129-
130-
if (navigationContext.IsCompleted && !navigationContext.IsForwordNavigation && !navigationContext.IsBackNavigation)
131-
throw new InvalidOperationException("Cannot add parameters after navigation is completed.");
132-
133-
navigationContext.Parameters ??= new NavigationParameters();
134-
navigationContext.Parameters.AddRange(parameters);
135-
return navigationContext;
136-
}
137116
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using AsyncNavigation.Abstractions;
2+
using AsyncNavigation.Core;
3+
using System.Diagnostics.CodeAnalysis;
4+
5+
namespace AsyncNavigation;
6+
7+
public static class NavigationContextExtensions
8+
{
9+
public static bool TryResolveView(this NavigationContext navigationContext, [MaybeNullWhen(false)] out IView view)
10+
{
11+
if (navigationContext.Target.IsSet)
12+
{
13+
view = navigationContext.Target.Value!;
14+
return true;
15+
}
16+
view = default;
17+
return false;
18+
}
19+
20+
public static bool TryResolveNavigationAware(this NavigationContext navigationContext, [MaybeNullWhen(false)] out INavigationAware aware)
21+
{
22+
if (navigationContext.Target.IsSet)
23+
{
24+
if(navigationContext.Target.Value is not null
25+
&& navigationContext.Target.Value.DataContext is INavigationAware navAware)
26+
{
27+
aware = navAware;
28+
return true;
29+
}
30+
}
31+
aware = default;
32+
return false;
33+
}
34+
35+
public static bool TryResolveViewAndAware(this NavigationContext navigationContext,
36+
[MaybeNullWhen(false)] out IView view,
37+
[MaybeNullWhen(false)] out INavigationAware aware)
38+
{
39+
view = default;
40+
aware = default;
41+
42+
if (!navigationContext.Target.IsSet)
43+
return false;
44+
45+
var target = navigationContext.Target.Value;
46+
if (target is null)
47+
return false;
48+
49+
view = target;
50+
51+
if (target.DataContext is INavigationAware navAware)
52+
{
53+
aware = navAware;
54+
return true;
55+
}
56+
return false;
57+
}
58+
public static NavigationContext WithParameter(this NavigationContext navigationContext, string key, object value)
59+
{
60+
if (navigationContext.IsCompleted && !navigationContext.IsForwordNavigation && !navigationContext.IsBackNavigation)
61+
throw new InvalidOperationException("Cannot add parameters after navigation is completed.");
62+
63+
navigationContext.Parameters ??= new NavigationParameters();
64+
navigationContext.Parameters.Add(key, value);
65+
return navigationContext;
66+
}
67+
68+
public static NavigationContext WithParameters(this NavigationContext navigationContext, IEnumerable<KeyValuePair<string, object>> parameters)
69+
{
70+
71+
if (navigationContext.IsCompleted && !navigationContext.IsForwordNavigation && !navigationContext.IsBackNavigation)
72+
throw new InvalidOperationException("Cannot add parameters after navigation is completed.");
73+
74+
navigationContext.Parameters ??= new NavigationParameters();
75+
navigationContext.Parameters.AddRange(parameters);
76+
return navigationContext;
77+
}
78+
79+
}

0 commit comments

Comments
 (0)