Skip to content

Commit 88abc18

Browse files
committed
avaloniaui ok
1 parent 1f2e472 commit 88abc18

27 files changed

Lines changed: 601 additions & 132 deletions

src/Lemon.ModuleNavigation.Avaloniaui/AssemblyInfo.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33
[assembly: XmlnsPrefix("https://github.com/NeverMorewd/Lemon.ModuleNavigation", "lm")]
44
[assembly: XmlnsDefinition("https://github.com/NeverMorewd/Lemon.ModuleNavigation", "Lemon.ModuleNavigation")]
5-
[assembly: XmlnsDefinition("https://github.com/NeverMorewd/Lemon.ModuleNavigation", "Lemon.ModuleNavigation.Avaloniaui")]
5+
[assembly: XmlnsDefinition("https://github.com/NeverMorewd/Lemon.ModuleNavigation", "Lemon.ModuleNavigation.Avaloniaui")]
6+
[assembly: XmlnsDefinition("https://github.com/NeverMorewd/Lemon.ModuleNavigation", "Lemon.ModuleNavigation.Avaloniaui.Regions")]

src/Lemon.ModuleNavigation.Avaloniaui/Lemon.ModuleNavigation.Avaloniaui.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,13 @@
1515

1616
<ItemGroup>
1717
<AvaloniaXaml Remove="bin\**" />
18+
<AvaloniaXaml Remove="RegionsOld\**" />
1819
<Compile Remove="bin\**" />
20+
<Compile Remove="RegionsOld\**" />
1921
<EmbeddedResource Remove="bin\**" />
22+
<EmbeddedResource Remove="RegionsOld\**" />
2023
<None Remove="bin\**" />
24+
<None Remove="RegionsOld\**" />
2125
</ItemGroup>
2226

2327
<ItemGroup>

src/Lemon.ModuleNavigation.Avaloniaui/NavigationExtension.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,14 +179,6 @@ private static void UnloadModule(object? sender, RoutedEventArgs e)
179179
}
180180
}
181181
}
182-
else if (tabItem.DataContext is NavigationContext navigationContext)
183-
{
184-
if (tabContainer.DataContext is IServiceAware serviceAware)
185-
{
186-
var regionManager = serviceAware.ServiceProvider.GetRequiredService<IRegionManager>();
187-
regionManager.RequestUnload(navigationContext);
188-
}
189-
}
190182
}
191183
}
192184
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
using Avalonia.Controls;
2+
using Avalonia.Controls.Templates;
3+
using Avalonia.Data;
4+
using Avalonia.Markup.Xaml.Templates;
5+
using Lemon.ModuleNavigation.Abstractions;
6+
using System.ComponentModel;
7+
using System.Runtime.CompilerServices;
8+
9+
namespace Lemon.ModuleNavigation.Avaloniaui.Regions;
10+
11+
public class ContentRegion : Region, IContentRegionContext<IDataTemplate>
12+
{
13+
private readonly ContentControl _contentControl;
14+
public ContentRegion(string name, ContentControl contentControl) : base(name)
15+
{
16+
_contentControl = contentControl;
17+
SetBindingContentTemplate();
18+
SetBindingContent();
19+
}
20+
21+
private object? _content;
22+
public object? Content
23+
{
24+
get => _content;
25+
set
26+
{
27+
_content = value;
28+
OnPropertyChanged();
29+
}
30+
}
31+
32+
private IDataTemplate? _contentTemplate;
33+
public IDataTemplate? ContentTemplate
34+
{
35+
get => _contentTemplate;
36+
set
37+
{
38+
_contentTemplate = value;
39+
OnPropertyChanged();
40+
}
41+
}
42+
43+
public event PropertyChangedEventHandler? PropertyChanged;
44+
45+
/// <summary>
46+
/// When Views with same ViewName were found, the latest one will be picked.
47+
/// </summary>
48+
/// <param name="target"></param>
49+
public override void Activate(NavigationContext target)
50+
{
51+
if (ViewCache.TryGetValue(target, out IView? accurateView))
52+
{
53+
target.View = accurateView;
54+
Content = target;
55+
}
56+
else if (ViewNameCache.TryGetValue(target.ViewName, out IView? view)
57+
&& view.DataContext is INavigationAware navigationAware
58+
&& navigationAware.IsNavigationTarget(target))
59+
{
60+
var context = Contexts.First(c => c.ViewName == target.ViewName);
61+
context.View = view;
62+
Content = context;
63+
}
64+
else
65+
{
66+
Contexts.Add(target);
67+
Content = target;
68+
}
69+
}
70+
71+
public override void DeActivate(string regionName)
72+
{
73+
if (Content is NavigationContext current)
74+
{
75+
if (current.ViewName == regionName)
76+
{
77+
Contexts.Remove(current);
78+
Content = null;
79+
}
80+
}
81+
}
82+
public override void DeActivate(NavigationContext navigationContext)
83+
{
84+
if (Content is NavigationContext current)
85+
{
86+
if (NavigationContext.ViewNameComparer.Equals(current, navigationContext))
87+
{
88+
Contexts.Remove(current);
89+
Content = null;
90+
}
91+
}
92+
}
93+
94+
protected virtual void SetBindingContentTemplate()
95+
{
96+
ContentTemplate = RegionContentTemplate;
97+
_contentControl.Bind(ContentControl.ContentTemplateProperty,
98+
new Binding(nameof(ContentTemplate))
99+
{
100+
Source = this,
101+
Mode = BindingMode.TwoWay
102+
});
103+
}
104+
protected virtual void SetBindingContent()
105+
{
106+
_contentControl.Bind(ContentControl.ContentProperty,
107+
new Binding(nameof(Content))
108+
{
109+
Source = this,
110+
Mode = BindingMode.TwoWay
111+
});
112+
}
113+
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
114+
{
115+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
116+
}
117+
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
using Avalonia.Controls;
2+
using Avalonia.Controls.Primitives;
3+
using Avalonia.Controls.Templates;
4+
using Avalonia.Data;
5+
using Avalonia.Markup.Xaml.Templates;
6+
using Lemon.ModuleNavigation.Abstractions;
7+
using System.ComponentModel;
8+
using System.Runtime.CompilerServices;
9+
10+
namespace Lemon.ModuleNavigation.Avaloniaui.Regions;
11+
12+
public class ItemsRegion : Region, IItemsRegionDataContext<IDataTemplate>
13+
{
14+
private readonly ItemsControl _itemsControl;
15+
public ItemsRegion(string name, ItemsControl itemsControl) : base(name)
16+
{
17+
_itemsControl = itemsControl;
18+
SetBindingItemTemplate();
19+
SetBindingSelectedItem();
20+
SetBindingItemsSource();
21+
}
22+
private object? _selectItem;
23+
public object? SelectedItem
24+
{
25+
get
26+
{
27+
return _selectItem;
28+
}
29+
set
30+
{
31+
_selectItem = value;
32+
OnPropertyChanged();
33+
}
34+
}
35+
36+
private IDataTemplate? _itemsTemplate;
37+
public IDataTemplate? ItemTemplate
38+
{
39+
get => _itemsTemplate;
40+
set
41+
{
42+
_itemsTemplate = value;
43+
OnPropertyChanged();
44+
}
45+
}
46+
public event PropertyChangedEventHandler? PropertyChanged;
47+
48+
public override void ScrollIntoView(int index)
49+
{
50+
_itemsControl.ScrollIntoView(index);
51+
}
52+
public override void ScrollIntoView(NavigationContext item)
53+
{
54+
_itemsControl.ScrollIntoView(item);
55+
}
56+
57+
/// <summary>
58+
/// When Views with same ViewName were found, the earliest one will be picked.
59+
/// </summary>
60+
/// <param name="target"></param>
61+
public override void Activate(NavigationContext target)
62+
{
63+
try
64+
{
65+
if (ViewCache.TryGetValue(target, out IView? accurateView))
66+
{
67+
target.View = accurateView;
68+
SelectedItem = target;
69+
return;
70+
}
71+
var context = Contexts.FirstOrDefault(c => c.ViewName == target.ViewName);
72+
if (context is not null
73+
&& context.View is not null
74+
&& context.View.DataContext is INavigationAware navigationAware
75+
&& navigationAware.IsNavigationTarget(target))
76+
{
77+
SelectedItem = context;
78+
return;
79+
}
80+
Contexts.Add(target);
81+
SelectedItem = target;
82+
}
83+
finally
84+
{
85+
ScrollIntoView((SelectedItem as NavigationContext)!);
86+
}
87+
}
88+
public override void DeActivate(string viewName)
89+
{
90+
Contexts.Remove(Contexts.Last(c => c.ViewName == viewName));
91+
}
92+
public override void DeActivate(NavigationContext navigationContext)
93+
{
94+
Contexts.Remove(navigationContext);
95+
}
96+
public void Add(NavigationContext item)
97+
{
98+
Contexts.Add(item);
99+
}
100+
101+
protected virtual void SetBindingItemsSource()
102+
{
103+
_itemsControl.Bind(ItemsControl.ItemsSourceProperty,
104+
new Binding(nameof(Contexts))
105+
{
106+
Source = this
107+
});
108+
}
109+
protected virtual void SetBindingItemTemplate()
110+
{
111+
ItemTemplate = RegionContentTemplate;
112+
_itemsControl.Bind(ItemsControl.ItemTemplateProperty,
113+
new Binding(nameof(ItemTemplate))
114+
{
115+
Source = this
116+
});
117+
}
118+
protected virtual void SetBindingSelectedItem()
119+
{
120+
if (_itemsControl is SelectingItemsControl selector)
121+
{
122+
selector.Bind(SelectingItemsControl.SelectedItemProperty,
123+
new Binding(nameof(SelectedItem))
124+
{
125+
Source = this,
126+
Mode = BindingMode.TwoWay
127+
});
128+
}
129+
}
130+
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
131+
{
132+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
133+
}
134+
}

0 commit comments

Comments
 (0)