-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathItemsRegion.cs
More file actions
134 lines (128 loc) · 3.92 KB
/
ItemsRegion.cs
File metadata and controls
134 lines (128 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Markup.Xaml.Templates;
using Lemon.ModuleNavigation.Abstractions;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace Lemon.ModuleNavigation.Avaloniaui.Regions;
public class ItemsRegion : Region, IItemsRegionDataContext<IDataTemplate>
{
private readonly ItemsControl _itemsControl;
public ItemsRegion(string name, ItemsControl itemsControl) : base(name)
{
_itemsControl = itemsControl;
SetBindingItemTemplate();
SetBindingSelectedItem();
SetBindingItemsSource();
}
private object? _selectItem;
public object? SelectedItem
{
get
{
return _selectItem;
}
set
{
_selectItem = value;
OnPropertyChanged();
}
}
private IDataTemplate? _itemsTemplate;
public IDataTemplate? ItemTemplate
{
get => _itemsTemplate;
set
{
_itemsTemplate = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler? PropertyChanged;
public override void ScrollIntoView(int index)
{
_itemsControl.ScrollIntoView(index);
}
public override void ScrollIntoView(NavigationContext item)
{
_itemsControl.ScrollIntoView(item);
}
/// <summary>
/// When Views with same ViewName were found, the earliest one will be picked.
/// </summary>
/// <param name="target"></param>
public override void Activate(NavigationContext target)
{
try
{
if (ViewCache.TryGetValue(target, out IView? accurateView))
{
target.View = accurateView;
SelectedItem = target;
return;
}
var context = Contexts.FirstOrDefault(c => c.ViewName == target.ViewName);
if (context is not null
&& context.View is not null
&& context.View.DataContext is INavigationAware navigationAware
&& navigationAware.IsNavigationTarget(target))
{
SelectedItem = context;
return;
}
Contexts.Add(target);
SelectedItem = target;
}
finally
{
ScrollIntoView((SelectedItem as NavigationContext)!);
}
}
public override void DeActivate(string viewName)
{
Contexts.Remove(Contexts.Last(c => c.ViewName == viewName));
}
public override void DeActivate(NavigationContext navigationContext)
{
Contexts.Remove(navigationContext);
}
public void Add(NavigationContext item)
{
Contexts.Add(item);
}
protected virtual void SetBindingItemsSource()
{
_itemsControl.Bind(ItemsControl.ItemsSourceProperty,
new Binding(nameof(Contexts))
{
Source = this
});
}
protected virtual void SetBindingItemTemplate()
{
ItemTemplate = RegionContentTemplate;
_itemsControl.Bind(ItemsControl.ItemTemplateProperty,
new Binding(nameof(ItemTemplate))
{
Source = this
});
}
protected virtual void SetBindingSelectedItem()
{
if (_itemsControl is SelectingItemsControl selector)
{
selector.Bind(SelectingItemsControl.SelectedItemProperty,
new Binding(nameof(SelectedItem))
{
Source = this,
Mode = BindingMode.TwoWay
});
}
}
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}