@@ -43,6 +43,7 @@ partial class FrameworkElement : IFrameworkElement_EffectiveViewport
43
43
private event TypedEventHandler < _This , EffectiveViewportChangedEventArgs > ? _effectiveViewportChanged ;
44
44
private bool _hasNewHandler ;
45
45
private List < IFrameworkElement_EffectiveViewport > ? _childrenInterestedInViewportUpdates ;
46
+ private bool _isEnumeratingChildrenInterestedInViewportUpdates ;
46
47
private IDisposable ? _parentViewportUpdatesSubscription ;
47
48
private ViewportInfo _parentViewport = ViewportInfo . Empty ; // WARNING: Stored in parent's coordinates space, use GetParentViewport()
48
49
private ViewportInfo _lastEffectiveViewport ;
@@ -153,12 +154,21 @@ IDisposable IFrameworkElement_EffectiveViewport.RequestViewportUpdates(bool isIn
153
154
Uno . UI . Extensions . DependencyObjectExtensions . GetChildren ( this ) . OfType < IFrameworkElement_EffectiveViewport > ( ) . Contains ( child )
154
155
|| ( child as _View ) ? . FindFirstAncestor < IFrameworkElement_EffectiveViewport > ( ) == this ) ;
155
156
156
- ( _childrenInterestedInViewportUpdates ??= new ( ) ) . Add ( child ) ;
157
+ var childrenInterestedInViewportUpdates = _childrenInterestedInViewportUpdates switch
158
+ {
159
+ null => ( _childrenInterestedInViewportUpdates = new ( ) ) ,
160
+ _ when _isEnumeratingChildrenInterestedInViewportUpdates => ( _childrenInterestedInViewportUpdates = new ( _childrenInterestedInViewportUpdates ) ) ,
161
+ _ => _childrenInterestedInViewportUpdates ,
162
+ } ;
163
+ childrenInterestedInViewportUpdates . Add ( child ) ;
157
164
ReconfigureViewportPropagation ( isInternalUpdate , child ) ;
158
165
159
166
return Disposable . Create ( ( ) =>
160
167
{
161
- _childrenInterestedInViewportUpdates ! . Remove ( child ) ;
168
+ var childrenInterestedInViewportUpdates = _isEnumeratingChildrenInterestedInViewportUpdates
169
+ ? ( _childrenInterestedInViewportUpdates = new ( _childrenInterestedInViewportUpdates ) )
170
+ : _childrenInterestedInViewportUpdates ! ;
171
+ childrenInterestedInViewportUpdates . Remove ( child ) ;
162
172
ReconfigureViewportPropagation ( ) ;
163
173
} ) ;
164
174
}
@@ -351,9 +361,19 @@ private void PropagateEffectiveViewportChange(
351
361
352
362
if ( _childrenInterestedInViewportUpdates is { Count : > 0 } && ( isInitial || viewportUpdated ) )
353
363
{
354
- foreach ( var child in _childrenInterestedInViewportUpdates )
364
+ _isEnumeratingChildrenInterestedInViewportUpdates = true ;
365
+ var enumerator = _childrenInterestedInViewportUpdates . GetEnumerator ( ) ;
366
+ try
367
+ {
368
+ while ( enumerator . MoveNext ( ) )
369
+ {
370
+ enumerator . Current ! . OnParentViewportChanged ( isInitial , isInternal , this , viewport ) ;
371
+ }
372
+ }
373
+ finally
355
374
{
356
- child . OnParentViewportChanged ( isInitial , isInternal , this , viewport ) ;
375
+ _isEnumeratingChildrenInterestedInViewportUpdates = false ;
376
+ enumerator . Dispose ( ) ;
357
377
}
358
378
}
359
379
}
0 commit comments