Skip to content

Commit 5b83193

Browse files
authored
Merge pull request #32 from NeverMorewd/replay-navigation
fix onnavigatedfrom
2 parents 999a77f + 87372da commit 5b83193

File tree

10 files changed

+73
-31
lines changed

10 files changed

+73
-31
lines changed

src/Lemon.ModuleNavigation.Avaloniaui/Regions/AvaloniauiRegion.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ namespace Lemon.ModuleNavigation.Avaloniaui.Regions
1010
public abstract class AvaloniauiRegion : IRegion
1111
{
1212
private readonly Dictionary<string, IView> _viewCache;
13+
private readonly ConcurrentItem<(IView, INavigationAware)> _current;
1314
public AvaloniauiRegion()
1415
{
1516
_viewCache = [];
17+
_current = new();
1618
RegionTemplate = GetDataTemplate();
1719
}
1820
public abstract string Name
@@ -41,24 +43,30 @@ private IDataTemplate GetDataTemplate()
4143
{
4244
return default;
4345
}
44-
if (context.RequestNew || !_viewCache.TryGetValue(context.ViewName, out IView? view))
46+
if (context.RequestNew || !_viewCache.TryGetValue(context.TargetViewName, out IView? view))
4547
{
46-
view = context.ServiceProvider.GetRequiredKeyedService<IView>(context.ViewName);
48+
view = context.ServiceProvider.GetRequiredKeyedService<IView>(context.TargetViewName);
4749

4850
var viewFullName = view.GetType().FullName;
4951

5052
context.Uri = new Uri($"avares://{viewFullName}.axaml");
51-
var viewModel = context.ServiceProvider.GetRequiredKeyedService<INavigationAware>(context.ViewName);
52-
viewModel.OnNavigatedTo(context);
53-
if (viewModel.IsNavigationTarget(context))
53+
var navigationAware = context.ServiceProvider.GetRequiredKeyedService<INavigationAware>(context.TargetViewName);
54+
if (_current.TryTakeData(out (IView, INavigationAware) data))
5455
{
55-
view.DataContext = viewModel;
56+
data.Item2.OnNavigatedFrom(context);
57+
}
58+
if (navigationAware.IsNavigationTarget(context))
59+
{
60+
view.DataContext = navigationAware;
61+
navigationAware.OnNavigatedTo(context);
62+
_current.SetData((view, navigationAware));
5663
}
5764
else
5865
{
5966
return default;
6067
}
61-
_viewCache.TryAdd(context.ViewName, view);
68+
69+
_viewCache.TryAdd(context.TargetViewName, view);
6270
}
6371
return view as Control;
6472
});

src/Lemon.ModuleNavigation.Avaloniaui/Regions/ContentRegion.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public override void Activate(NavigationContext target)
3838
{
3939
if(Content is NavigationContext current)
4040
{
41-
if (target.ViewName == current.ViewName)
41+
if (target.TargetViewName == current.TargetViewName)
4242
{
4343
return;
4444
}

src/Lemon.ModuleNavigation.Sample/ViewModels/MainViewModel.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public MainViewModel(IEnumerable<IModule> modules,
3030
_dialogService = dialogService;
3131
_regionManager = regionManager;
3232
// default view
33-
_navigationService.NavigateToView("ContentRegion", "ViewAlpha", false);
33+
_navigationService.RequestViewNavigation("ContentRegion", "ViewAlpha", false);
3434
Modules = new ObservableCollection<IModule>(modules);
3535
ToViewCommand = ReactiveCommand.Create<string>(content =>
3636
{
@@ -42,10 +42,10 @@ public MainViewModel(IEnumerable<IModule> modules,
4242
requestNew = true;
4343

4444
}
45-
_navigationService.NavigateToView("ContentRegion", viewName, requestNew);
46-
_navigationService.NavigateToView("TabRegion", viewName, requestNew);
47-
_navigationService.NavigateToView("ItemsRegion", viewName, requestNew);
48-
_navigationService.NavigateToView("TransitioningContentRegion", viewName, requestNew);
45+
_navigationService.RequestViewNavigation("ContentRegion", viewName, requestNew);
46+
_navigationService.RequestViewNavigation("TabRegion", viewName, requestNew);
47+
_navigationService.RequestViewNavigation("ItemsRegion", viewName, requestNew);
48+
_navigationService.RequestViewNavigation("TransitioningContentRegion", viewName, requestNew);
4949
});
5050
ToDialogCommand = ReactiveCommand.Create<string>(content =>
5151
{
@@ -78,7 +78,7 @@ public MainViewModel(IEnumerable<IModule> modules,
7878
});
7979
_regionManager.Subscribe<NavigationContext>(n =>
8080
{
81-
_logger.LogDebug($"Request to : {n.RegionName}.{n.ViewName}");
81+
_logger.LogDebug($"Request to : {n.RegionName}.{n.TargetViewName}");
8282
});
8383
_regionManager.Subscribe<IRegion>(r =>
8484
{

src/Lemon.ModuleNavigation/Abstracts/IViewNavigationService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ namespace Lemon.ModuleNavigation.Abstracts
55
public interface IViewNavigationService
66
{
77
IDisposable BindingViewNavigationHandler(IViewNavigationHandler handler);
8-
void NavigateToView(string regionName,
8+
void RequestViewNavigation(string regionName,
99
string viewKey,
1010
bool requestNew = false);
11-
void NavigateToView(string regionName,
11+
void RequestViewNavigation(string regionName,
1212
string viewKey,
1313
NavigationParameters parameters,
1414
bool requestNew = false);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Collections.Concurrent;
2+
3+
namespace Lemon.ModuleNavigation
4+
{
5+
public class ConcurrentItem<T>
6+
{
7+
private const int SIZE = 1;
8+
private readonly BlockingCollection<T> _collection = new(SIZE);
9+
public ConcurrentItem() { }
10+
11+
public void SetData(T data)
12+
{
13+
if (_collection.Count == SIZE)
14+
{
15+
_collection.Take();
16+
}
17+
_collection.Add(data);
18+
}
19+
20+
public T TakeData()
21+
{
22+
return _collection.Take();
23+
}
24+
25+
public bool TryTakeData(out T? data)
26+
{
27+
return _collection.TryTake(out data);
28+
}
29+
30+
public bool WaitForData(TimeSpan timeSpan, out T? data)
31+
{
32+
return _collection.TryTake(out data, timeSpan);
33+
}
34+
}
35+
36+
}

src/Lemon.ModuleNavigation/Core/NavigationContext.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ internal NavigationContext(string viewName,
99
bool requestNew,
1010
NavigationParameters? navigationParameters)
1111
{
12-
ViewName = viewName;
12+
TargetViewName = viewName;
1313
Parameters = navigationParameters;
1414
RequestNew = requestNew;
1515
RegionName = regionName;
@@ -18,7 +18,7 @@ internal NavigationContext(string viewName,
1818
}
1919
public static ViewNameComparer ViewNameComparer => new();
2020
public static StrictComparer StrictComparer => new();
21-
public string ViewName
21+
public string TargetViewName
2222
{
2323
get;
2424
private set;
@@ -50,7 +50,7 @@ public IServiceProvider ServiceProvider
5050
}
5151
public override string ToString()
5252
{
53-
return ViewName;
53+
return TargetViewName;
5454
}
5555
}
5656
public class ViewNameComparer : IEqualityComparer<NavigationContext>
@@ -59,12 +59,12 @@ public bool Equals(NavigationContext? x, NavigationContext? y)
5959
{
6060
if (x == null && y == null) return true;
6161
if (x == null || y == null) return false;
62-
return x.ViewName == y.ViewName;
62+
return x.TargetViewName == y.TargetViewName;
6363
}
6464

6565
public int GetHashCode(NavigationContext obj)
6666
{
67-
return obj.ViewName.GetHashCode();
67+
return obj.TargetViewName.GetHashCode();
6868
}
6969
}
7070
public class StrictComparer : IEqualityComparer<NavigationContext>

src/Lemon.ModuleNavigation/Core/NavigationService.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ public class NavigationService : INavigationService
88
{
99
private readonly List<IModuleNavigationHandler> _handlers = [];
1010
private readonly List<IViewNavigationHandler> _viewHandlers = [];
11+
12+
// reserve only one for now.
1113
private readonly ConcurrentStack<(IModule module, NavigationParameters parameter)> _bufferModule = [];
1214
private readonly ConcurrentStack<(string moduleName, NavigationParameters parameter)> _bufferModuleName = [];
1315
private readonly ConcurrentStack<(string regionName, string viewName, bool requestNew)> _bufferViewName = [];
@@ -36,7 +38,7 @@ public void RequestModuleNavigate(string moduleName, NavigationParameters parame
3638
}
3739
_bufferModuleName.Push((moduleName, parameters));
3840
}
39-
public void NavigateToView(string regionName,
41+
public void RequestViewNavigation(string regionName,
4042
string viewKey,
4143
bool requestNew = false)
4244
{
@@ -86,7 +88,7 @@ IDisposable IViewNavigationService.BindingViewNavigationHandler(IViewNavigationH
8688
});
8789
}
8890

89-
public void NavigateToView(string regionName,
91+
public void RequestViewNavigation(string regionName,
9092
string viewKey,
9193
NavigationParameters parameters,
9294
bool requestNew = false)

src/Lemon.ModuleNavigation/Internals/ConcurrentSet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace Lemon.ModuleNavigation.Internals
55
{
6-
internal class ConcurrentSet<T> : IEnumerable<T> where T : notnull
6+
internal sealed class ConcurrentSet<T> : IEnumerable<T> where T : notnull
77
{
88
private readonly ConcurrentDictionary<T, byte> _dict = new();
99

src/Lemon.ModuleNavigation/Internals/DisposableAction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace Lemon.ModuleNavigation.Internals
22
{
3-
internal class DisposableAction : IDisposable
3+
internal sealed class DisposableAction : IDisposable
44
{
55
private readonly Action _action;
66
private int _disposed;

src/Lemon.ModuleNavigation/Parameters/BaseParameters.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
using System;
2-
using System.Collections;
3-
using System.Collections.Generic;
1+
using System.Collections;
42
using System.ComponentModel;
5-
using System.Linq;
63
using System.Text;
7-
using System.Threading.Tasks;
84

95
namespace Lemon.ModuleNavigation.Parameters
106
{
@@ -55,7 +51,7 @@ public IEnumerable<T> GetValues<T>(string key) where T : notnull
5551
}
5652
public bool TryGetValue<T>(string key, out T? value) where T : notnull
5753
{
58-
return _entries.TryGetValue<T>(key, out value);
54+
return _entries.TryGetValue(key, out value);
5955
}
6056
IEnumerator IEnumerable.GetEnumerator()
6157
{

0 commit comments

Comments
 (0)