Skip to content

Commit 5b651c9

Browse files
committed
remove requestNew;wpf ok
1 parent 239533c commit 5b651c9

16 files changed

Lines changed: 214 additions & 160 deletions

File tree

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

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Lemon.ModuleNavigation.Abstractions;
2-
using Microsoft.Extensions.DependencyInjection;
32
using System.ComponentModel;
43
using System.Runtime.CompilerServices;
54
using System.Windows;
@@ -42,10 +41,30 @@ public DataTemplate? ContentTemplate
4241

4342
public event PropertyChangedEventHandler? PropertyChanged;
4443

44+
/// <summary>
45+
/// When Views with same ViewName were found, the latest one will be picked.
46+
/// </summary>
47+
/// <param name="target"></param>
4548
public override void Activate(NavigationContext target)
4649
{
47-
Content = target;
48-
Contexts.Add(target);
50+
if (ViewCache.TryGetValue(target, out IView? accurateView))
51+
{
52+
target.View = accurateView;
53+
Content = target;
54+
}
55+
else if (ViewNameCache.TryGetValue(target.ViewName, out IView? view)
56+
&& view.DataContext is INavigationAware navigationAware
57+
&& navigationAware.IsNavigationTarget(target))
58+
{
59+
var context = Contexts.First(c => c.ViewName == target.ViewName);
60+
context.View = view;
61+
Content = context;
62+
}
63+
else
64+
{
65+
Contexts.Add(target);
66+
Content = target;
67+
}
4968
}
5069

5170
public override void DeActivate(string regionName)
@@ -70,45 +89,10 @@ public override void DeActivate(NavigationContext navigationContext)
7089
}
7190
}
7291
}
73-
74-
protected override IView? ResolveView(NavigationContext context)
75-
{
76-
bool needNewView = !ViewNameCache.TryGetValue(context.ViewName, out IView? view);
77-
78-
if (!needNewView)
79-
{
80-
if (view!.DataContext is INavigationAware navigationAware
81-
&& !navigationAware.IsNavigationTarget(context))
82-
{
83-
needNewView = true;
84-
}
85-
}
86-
87-
if (needNewView)
88-
{
89-
view = context.ServiceProvider.GetRequiredKeyedService<IView>(context.ViewName);
90-
var navigationAware = context.ServiceProvider.GetRequiredKeyedService<INavigationAware>(context.ViewName);
91-
92-
if (Current.TryTakeData(out var previousData))
93-
{
94-
previousData.NavigationAware.OnNavigatedFrom(context);
95-
}
96-
97-
view.DataContext = navigationAware;
98-
navigationAware.OnNavigatedTo(context);
99-
navigationAware.RequestUnload += () =>
100-
{
101-
DeActivate(context);
102-
};
103-
Current.SetData((view, navigationAware));
104-
ViewNameCache[context.ViewName] = view;
105-
}
106-
107-
return view;
108-
}
92+
10993
protected virtual void SetBindingContentTemplate()
11094
{
111-
ContentTemplate = RegionTemplate;
95+
ContentTemplate = RegionContentTemplate;
11296
BindingOperations.SetBinding(_contentControl,
11397
ContentControl.ContentTemplateProperty,
11498
new Binding

src/Lemon.ModuleNavigation.Wpf/Regions/ItemsRegion.cs

Lines changed: 22 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Lemon.ModuleNavigation.Abstractions;
2-
using Microsoft.Extensions.DependencyInjection;
32
using System.ComponentModel;
43
using System.Runtime.CompilerServices;
54
using System.Windows;
@@ -53,34 +52,37 @@ public override void ScrollIntoView(NavigationContext item)
5352
{
5453
_itemsControl.ScrollIntoView(item);
5554
}
55+
56+
/// <summary>
57+
/// When Views with same ViewName were found, the earliest one will be picked.
58+
/// </summary>
59+
/// <param name="target"></param>
5660
public override void Activate(NavigationContext target)
5761
{
58-
if (!target.RequestNew)
62+
try
5963
{
60-
var targetContext = Contexts.FirstOrDefault(context =>
61-
{
62-
if (NavigationContext.ViewNameComparer.Equals(target, context))
63-
{
64-
return true;
65-
}
66-
return false;
67-
});
68-
if (targetContext == null)
64+
if (ViewCache.TryGetValue(target, out IView? accurateView))
6965
{
70-
Contexts.Add(target);
66+
target.View = accurateView;
7167
SelectedItem = target;
68+
return;
7269
}
73-
else
70+
var context = Contexts.FirstOrDefault(c => c.ViewName == target.ViewName);
71+
if (context is not null
72+
&& context.View is not null
73+
&& context.View.DataContext is INavigationAware navigationAware
74+
&& navigationAware.IsNavigationTarget(target))
7475
{
75-
SelectedItem = targetContext;
76+
SelectedItem = context;
77+
return;
7678
}
77-
}
78-
else
79-
{
8079
Contexts.Add(target);
8180
SelectedItem = target;
8281
}
83-
ScrollIntoView((SelectedItem as NavigationContext)!);
82+
finally
83+
{
84+
ScrollIntoView((SelectedItem as NavigationContext)!);
85+
}
8486
}
8587
public override void DeActivate(string viewName)
8688
{
@@ -93,43 +95,7 @@ public override void DeActivate(NavigationContext navigationContext)
9395
public void Add(NavigationContext item)
9496
{
9597
Contexts.Add(item);
96-
}
97-
98-
protected override IView? ResolveView(NavigationContext context)
99-
{
100-
bool needNewView = !ViewCache.TryGetValue(context.Guid, out IView? view);
101-
102-
if (!needNewView)
103-
{
104-
if (view!.DataContext is INavigationAware navigationAware
105-
&& !navigationAware.IsNavigationTarget(context))
106-
{
107-
needNewView = true;
108-
}
109-
}
110-
111-
if (needNewView)
112-
{
113-
view = context.ServiceProvider.GetRequiredKeyedService<IView>(context.ViewName);
114-
var navigationAware = context.ServiceProvider.GetRequiredKeyedService<INavigationAware>(context.ViewName);
115-
116-
if (Current.TryTakeData(out var previousData))
117-
{
118-
previousData.NavigationAware.OnNavigatedFrom(context);
119-
}
120-
121-
view.DataContext = navigationAware;
122-
navigationAware.OnNavigatedTo(context);
123-
navigationAware.RequestUnload += () =>
124-
{
125-
DeActivate(context);
126-
};
127-
Current.SetData((view, navigationAware));
128-
ViewCache[context.Guid] = view;
129-
}
130-
131-
return view;
132-
}
98+
}
13399

134100
protected virtual void SetBindingItemsSource()
135101
{
@@ -141,7 +107,7 @@ protected virtual void SetBindingItemsSource()
141107
}
142108
protected virtual void SetBindingItemTemplate()
143109
{
144-
ItemTemplate = RegionTemplate;
110+
ItemTemplate = RegionContentTemplate;
145111
BindingOperations.SetBinding(_itemsControl, ItemsControl.ItemTemplateProperty, new Binding
146112
{
147113
Source = this,

src/Lemon.ModuleNavigation.Wpf/Regions/Region.cs

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Lemon.ModuleNavigation.Abstractions;
22
using Lemon.ModuleNavigation.Core;
3+
using Microsoft.Extensions.DependencyInjection;
34
using System.Collections.Concurrent;
45
using System.Collections.ObjectModel;
56
using System.Collections.Specialized;
@@ -15,39 +16,43 @@ public Region(string name)
1516
Name = name;
1617
Current = new();
1718
ViewCache = [];
18-
ViewNameCache = [];
1919
Contexts = [];
20-
RegionTemplate = CreateRegionDataTemplate();
20+
RegionContentTemplate = CreateRegionDataTemplate();
2121
Contexts.CollectionChanged += Contexts_CollectionChanged;
2222
}
23-
24-
protected ConcurrentDictionary<Guid, IView> ViewCache
23+
protected ConcurrentItem<(IView View, INavigationAware NavigationAware)> Current
2524
{
2625
get;
2726
}
28-
protected ConcurrentDictionary<string, IView> ViewNameCache
27+
public string Name
2928
{
3029
get;
3130
}
32-
protected ConcurrentItem<(IView View, INavigationAware NavigationAware)> Current
31+
protected ConcurrentDictionary<NavigationContext, IView> ViewCache
3332
{
3433
get;
3534
}
36-
public string Name
35+
36+
protected ConcurrentDictionary<string, IView> ViewNameCache
3737
{
38-
get;
38+
get
39+
{
40+
return new(Contexts
41+
.GroupBy(kv => kv.ViewName)
42+
.Select(group => new KeyValuePair<string, IView>(
43+
group.Key,
44+
group.Last().View!)));
45+
}
3946
}
40-
4147
public ObservableCollection<NavigationContext> Contexts
4248
{
4349
get;
4450
}
4551

46-
public DataTemplate? RegionTemplate
52+
public DataTemplate? RegionContentTemplate
4753
{
4854
get;
4955
}
50-
5156
public virtual void ScrollIntoView(int index)
5257
{
5358
throw new NotImplementedException();
@@ -60,7 +65,31 @@ public virtual void ScrollIntoView(NavigationContext item)
6065
public abstract void DeActivate(string viewName);
6166
public abstract void DeActivate(NavigationContext target);
6267

63-
protected abstract IView? ResolveView(NavigationContext context);
68+
protected IView? ResolveView(NavigationContext context)
69+
{
70+
var view = context.View;
71+
if (view is null)
72+
{
73+
view = context.ServiceProvider.GetRequiredKeyedService<IView>(context.ViewName);
74+
var navigationAware = context.ServiceProvider.GetRequiredKeyedService<INavigationAware>(context.ViewName);
75+
76+
if (Current.TryTakeData(out var previousData))
77+
{
78+
previousData.NavigationAware.OnNavigatedFrom(context);
79+
}
80+
81+
view.DataContext = navigationAware;
82+
navigationAware.OnNavigatedTo(context);
83+
navigationAware.RequestUnload += () =>
84+
{
85+
DeActivate(context);
86+
};
87+
Current.SetData((view, navigationAware));
88+
context.View = view;
89+
ViewCache.AddOrUpdate(context, view, (key, value) => view);
90+
}
91+
return view;
92+
}
6493

6594
protected virtual void WhenContextsAdded(IEnumerable<NavigationContext> contexts)
6695
{
@@ -111,9 +140,7 @@ public NavigationContextToViewConverter(Region region)
111140
{
112141
if (value is NavigationContext context)
113142
{
114-
var view = _region.ResolveView(context);
115-
_region.ViewCache.AddOrUpdate(context.Guid, view!, (key, oldValue) => view!);
116-
return view;
143+
return _region.ResolveView(context);
117144
}
118145
return null;
119146
}

src/Lemon.ModuleNavigation.Wpf/Regions/TabRegion.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ public class TabRegion : ItemsRegion, IContentRegionContext<DataTemplate>
1111
public TabRegion(string name, TabControl tabControl) : base(name, tabControl)
1212
{
1313
_tabControl = tabControl;
14-
ContentTemplate = RegionTemplate;
14+
ContentTemplate = RegionContentTemplate;
1515
SetBindingContentTemplate();
1616
}
17+
1718
public object? Content
1819
{
19-
get;
20-
set;
20+
get => throw new NotImplementedException();
21+
set => throw new NotImplementedException();
2122
}
2223

2324
private DataTemplate? _contentTemplate;
@@ -32,9 +33,8 @@ public DataTemplate? ContentTemplate
3233
}
3334
protected override void SetBindingItemTemplate()
3435
{
35-
//
36+
//base.SetBindingItemTemplate();
3637
}
37-
3838
protected virtual void SetBindingContentTemplate()
3939
{
4040
BindingOperations.SetBinding(_tabControl,

src/Lemon.ModuleNavigation.WpfSample/MainWindowViewModel.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ public class MainWindowViewModel : ReactiveObject, IServiceAware
1111
private readonly INavigationService _navigationService;
1212
private readonly IDialogService _dialogService;
1313
private readonly IRegionManager _regionManager;
14-
public MainWindowViewModel(INavigationService navigationService,
14+
public MainWindowViewModel(INavigationService navigationService,
1515
IDialogService dialogService,
1616
IRegionManager regionManager,
1717
IServiceProvider serviceProvider)
1818
{
1919
_dialogService = dialogService;
2020
_regionManager = regionManager;
2121
_navigationService = navigationService;
22-
_navigationService.RequestViewNavigation("ContentRegion", "ViewAlpha", false);
22+
_navigationService.RequestViewNavigation("ContentRegion", "ViewAlpha");
2323
ServiceProvider = serviceProvider;
24-
NavigateToViewCommand = ReactiveCommand.Create<string>(content =>
24+
NavigateToViewCommand = ReactiveCommand.Create<string>(content =>
2525
{
2626
var viewName = content;
2727
var requestNew = false;
@@ -31,9 +31,9 @@ public MainWindowViewModel(INavigationService navigationService,
3131
requestNew = true;
3232

3333
}
34-
_navigationService.RequestViewNavigation("ContentRegion", viewName, new NavigationParameters { { "requestNew", requestNew } }, requestNew);
35-
_navigationService.RequestViewNavigation("TabRegion", viewName, new NavigationParameters { { "requestNew", requestNew } }, requestNew);
36-
_navigationService.RequestViewNavigation("ItemsRegion", viewName, new NavigationParameters { { "requestNew", requestNew } }, requestNew);
34+
_navigationService.RequestViewNavigation("ContentRegion", viewName, new NavigationParameters { { "requestNew", requestNew } });
35+
_navigationService.RequestViewNavigation("TabRegion", viewName, new NavigationParameters { { "requestNew", requestNew } });
36+
_navigationService.RequestViewNavigation("ItemsRegion", viewName, new NavigationParameters { { "requestNew", requestNew } });
3737
});
3838

3939
ShowCommand = ReactiveCommand.Create<string>(content =>
@@ -84,7 +84,6 @@ await _dialogService.ShowDialog(content,
8484
{
8585
_regionManager.RequestUnload(context);
8686
});
87-
8887
}
8988

9089
public IServiceProvider ServiceProvider

src/Lemon.ModuleNavigation.WpfSample/ViewModels/ViewAlphaViewModel.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ public void OnDialogOpened(IDialogParameters? parameters)
4545

4646
public override bool IsNavigationTarget(NavigationContext navigationContext)
4747
{
48-
return !navigationContext.RequestNew;
48+
if (navigationContext.Parameters is not null)
49+
{
50+
if (navigationContext.Parameters.TryGetValue("requestNew", out bool requestNew))
51+
{
52+
return !requestNew;
53+
}
54+
}
55+
return true;
4956
}
5057
}

0 commit comments

Comments
 (0)