1
- #nullable disable
2
- using System ;
3
- using System . Collections ;
4
- using System . Collections . Specialized ;
5
1
using System . ComponentModel ;
2
+ using Microsoft . Maui . Controls . Shapes ;
6
3
using Microsoft . Maui . Graphics ;
7
4
8
5
namespace Microsoft . Maui . Controls
9
6
{
10
7
internal class IndicatorStackLayout : StackLayout
11
8
{
12
- IndicatorView _indicatorView ;
9
+ readonly IndicatorView _indicatorView ;
13
10
public IndicatorStackLayout ( IndicatorView indicatorView )
14
11
{
15
12
_indicatorView = indicatorView ;
16
13
Orientation = StackOrientation . Horizontal ;
17
- _indicatorView . PropertyChanged += _indicatorViewPropertyChanged ;
14
+ _indicatorView . PropertyChanged += IndicatorViewPropertyChanged ;
18
15
}
19
16
20
- void _indicatorViewPropertyChanged ( object sender , PropertyChangedEventArgs e )
17
+ protected override void OnChildAdded ( Element child )
18
+ {
19
+ base . OnChildAdded ( child ) ;
20
+
21
+ if ( child is View view )
22
+ {
23
+ var tapGestureRecognizer = new TapGestureRecognizer
24
+ {
25
+ Command = new Command ( sender => _indicatorView . Position = Children . IndexOf ( sender ) ) ,
26
+ CommandParameter = view
27
+ } ;
28
+ view . GestureRecognizers . Add ( tapGestureRecognizer ) ;
29
+ }
30
+ }
31
+
32
+ void IndicatorViewPropertyChanged ( object ? sender , PropertyChangedEventArgs e )
21
33
{
22
34
if ( e . PropertyName == IndicatorView . IndicatorsShapeProperty . PropertyName
23
35
|| e . PropertyName == IndicatorView . IndicatorTemplateProperty . PropertyName )
@@ -53,8 +65,7 @@ internal void ResetIndicators()
53
65
try
54
66
{
55
67
BatchBegin ( ) ;
56
- Children . Clear ( ) ;
57
- AddExtraIndicatorItems ( ) ;
68
+ BindIndicatorItems ( ) ;
58
69
}
59
70
finally
60
71
{
@@ -75,11 +86,10 @@ internal void ResetIndicatorCount(int oldCount)
75
86
76
87
if ( oldCount > _indicatorView . Count )
77
88
{
78
- RemoveRedundantIndicatorItems ( ) ;
79
89
return ;
80
90
}
81
91
82
- AddExtraIndicatorItems ( ) ;
92
+ BindIndicatorItems ( ) ;
83
93
}
84
94
finally
85
95
{
@@ -100,6 +110,10 @@ void ResetIndicatorStylesNonBatch()
100
110
var selectedIndex = position >= maxVisible ? maxVisible - 1 : position ;
101
111
bool isSelected = index == selectedIndex ;
102
112
var visualElement = Children [ index ] as VisualElement ;
113
+ if ( visualElement is null )
114
+ {
115
+ return ;
116
+ }
103
117
104
118
visualElement . BackgroundColor = isSelected
105
119
? GetColorOrDefault ( _indicatorView . SelectedIndicatorColor , Colors . Gray )
@@ -115,49 +129,34 @@ void ResetIndicatorStylesNonBatch()
115
129
IsVisible = indicatorCount > 1 || ! _indicatorView . HideSingle ;
116
130
}
117
131
118
- Color GetColorOrDefault ( Color color , Color defaultColor ) => color ?? defaultColor ;
132
+ Color GetColorOrDefault ( Color ? color , Color defaultColor ) => color ?? defaultColor ;
119
133
120
- void AddExtraIndicatorItems ( )
134
+ void BindIndicatorItems ( )
121
135
{
122
- var indicatorCount = _indicatorView . Count ;
123
- var indicatorMaximumVisible = _indicatorView . MaximumVisible ;
124
- var indicatorSize = _indicatorView . IndicatorSize ;
125
- var indicatorTemplate = _indicatorView . IndicatorTemplate ;
126
-
127
- var oldCount = Children . Count ;
128
- for ( var i = 0 ; i < indicatorCount - oldCount && i < indicatorMaximumVisible - oldCount ; i ++ )
136
+ var indicatorSize = _indicatorView . IndicatorSize > 0 ? _indicatorView . IndicatorSize : 10 ;
137
+ var indicatorTemplate = _indicatorView . IndicatorTemplate ??= new DataTemplate ( ( ) => new Border
129
138
{
130
- var size = indicatorSize > 0 ? indicatorSize : 10 ;
131
- var indicator = indicatorTemplate ? . CreateContent ( ) as View ?? new Frame
139
+ Padding = 0 ,
140
+ VerticalOptions = LayoutOptions . Center ,
141
+ HorizontalOptions = LayoutOptions . Center ,
142
+ WidthRequest = indicatorSize ,
143
+ HeightRequest = indicatorSize ,
144
+ StrokeShape = new RoundRectangle ( )
132
145
{
133
- Padding = 0 ,
134
- HasShadow = false ,
135
- BorderColor = Colors . Transparent ,
136
- VerticalOptions = LayoutOptions . Center ,
137
- HorizontalOptions = LayoutOptions . Center ,
138
- WidthRequest = size ,
139
- HeightRequest = size ,
140
- CornerRadius = _indicatorView . IndicatorsShape == IndicatorShape . Circle ? ( float ) size / 2 : 0
141
- } ;
142
- var tapGestureRecognizer = new TapGestureRecognizer ( ) ;
143
- tapGestureRecognizer . Tapped += ( sender , args ) => _indicatorView . Position = Children . IndexOf ( sender as View ) ;
144
- indicator . GestureRecognizers . Add ( tapGestureRecognizer ) ;
145
- Children . Add ( indicator ) ;
146
- }
147
- }
148
-
149
- void RemoveRedundantIndicatorItems ( )
150
- {
151
- var indicatorCount = _indicatorView . Count ;
152
- while ( Children . Count > indicatorCount )
153
- {
154
- Children . RemoveAt ( 0 ) ;
155
- }
146
+ CornerRadius = _indicatorView . IndicatorsShape == IndicatorShape . Circle
147
+ ? ( float ) indicatorSize / 2
148
+ : 0 ,
149
+ Stroke = Colors . Transparent
150
+ }
151
+ } ) ;
152
+
153
+ BindableLayout . SetItemsSource ( this , _indicatorView . ItemsSource ) ;
154
+ BindableLayout . SetItemTemplate ( this , indicatorTemplate ) ;
156
155
}
157
156
158
157
public void Remove ( )
159
158
{
160
- _indicatorView . PropertyChanged -= _indicatorViewPropertyChanged ;
159
+ _indicatorView . PropertyChanged -= IndicatorViewPropertyChanged ;
161
160
}
162
161
}
163
- }
162
+ }
0 commit comments