22using System ;
33using System . Collections ;
44using System . Collections . Specialized ;
5+ using System . Linq ;
56using Microsoft . Maui . Controls . Internals ;
67
78namespace Microsoft . Maui . Controls
@@ -371,6 +372,7 @@ void CreateChildren()
371372 if ( childrenCount == 1 && layoutChildren [ 0 ] == _currentEmptyView )
372373 {
373374 layout . RemoveAt ( 0 ) ;
375+ _currentEmptyView . DisconnectHandlers ( ) ;
374376 childrenCount = 0 ;
375377 }
376378
@@ -394,11 +396,15 @@ void CreateChildren()
394396 // Remove exceeding items
395397 while ( index <= -- childrenCount )
396398 {
397- var child = ( BindableObject ) layoutChildren [ childrenCount ] ! ;
399+ IView child = ( IView ) layoutChildren [ childrenCount ] ! ;
398400 layout . RemoveAt ( childrenCount ) ;
401+
402+ // Disconnect platform view so when we clear binding context it doesn't run mappers
403+ child . DisconnectHandlers ( ) ;
404+
399405 // It's our responsibility to clear the BindingContext for the children
400406 // Given that we've set them manually in CreateItemView
401- child . BindingContext = null ;
407+ ClearBindingContext ( child ) ;
402408 }
403409 }
404410
@@ -413,7 +419,7 @@ bool TryAddEmptyView(IBindableLayout layout, out IEnumerator enumerator)
413419 // We may have a single child that is either the old empty view or a generated item
414420 if ( layoutChildren . Count == 1 )
415421 {
416- var maybeEmptyView = ( View ) layoutChildren [ 0 ] ! ;
422+ var maybeEmptyView = ( IView ) layoutChildren [ 0 ] ! ;
417423
418424 // If the current empty view is already in place we have nothing to do
419425 if ( maybeEmptyView == _currentEmptyView )
@@ -425,11 +431,10 @@ bool TryAddEmptyView(IBindableLayout layout, out IEnumerator enumerator)
425431 // So remove it to make room for the new empty view
426432 layout . RemoveAt ( 0 ) ;
427433
434+ // Disconnect platform view so when we clear binding context it doesn't run mappers
435+ maybeEmptyView . DisconnectHandlers ( ) ;
428436 // If this is a generated item, we need to clear the BindingContext
429- if ( maybeEmptyView . IsSet ( BindableLayoutTemplateProperty ) )
430- {
431- maybeEmptyView . ClearValue ( BindableObject . BindingContextProperty ) ;
432- }
437+ ClearBindingContext ( maybeEmptyView ) ;
433438 }
434439 else if ( layoutChildren . Count > 1 )
435440 {
@@ -452,14 +457,19 @@ bool TryAddEmptyView(IBindableLayout layout, out IEnumerator enumerator)
452457
453458 void ClearChildren ( IBindableLayout layout )
454459 {
455- var index = layout . Children . Count ;
456- while ( -- index >= 0 )
460+ var layoutChildren = layout . Children . OfType < IView > ( ) . ToArray ( ) ;
461+ layout . Clear ( ) ;
462+
463+ foreach ( var child in layoutChildren )
457464 {
458- var child = ( View ) layout . Children [ index ] ! ;
459- layout . RemoveAt ( index ) ;
465+ // Disconnect platform view so when we clear binding context it doesn't run mappers
466+ child . DisconnectHandlers ( ) ;
460467
461468 // It's our responsibility to clear the manually-set BindingContext for the generated children
462- child . ClearValue ( BindableObject . BindingContextProperty ) ;
469+ if ( child is BindableObject bindable )
470+ {
471+ bindable . ClearValue ( BindableObject . BindingContextProperty ) ;
472+ }
463473 }
464474 }
465475
@@ -515,18 +525,21 @@ void ItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArg
515525 if ( layoutChildren . Count == 1 && layoutChildren [ 0 ] == _currentEmptyView )
516526 {
517527 layout . RemoveAt ( 0 ) ;
528+ _currentEmptyView . DisconnectHandlers ( ) ;
518529 }
519530
520531 layout . Insert ( CreateItemView ( item , SelectTemplate ( item , layout ) ) , index ) ;
521532 } ,
522533 removeAt : ( item , index ) =>
523534 {
524- var child = ( View ) layout . Children [ index ] ! ;
535+ var child = ( IView ) layout . Children [ index ] ! ;
525536 layout . RemoveAt ( index ) ;
526537
538+ // Disconnect platform view so when we clear binding context it doesn't run mappers
539+ child . DisconnectHandlers ( ) ;
527540 // It's our responsibility to clear the BindingContext for the children
528541 // Given that we've set them manually in CreateItemView
529- child . BindingContext = null ;
542+ ClearBindingContext ( child ) ;
530543
531544 // If we removed the last item, we need to insert the empty view
532545 if ( layout . Children . Count == 0 && _currentEmptyView != null )
@@ -540,18 +553,18 @@ void ItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArg
540553 void ReplaceChild ( object item , IBindableLayout layout , IList layoutChildren , int index )
541554 {
542555 var template = SelectTemplate ( item , layout ) ;
543- var child = ( BindableObject ) layoutChildren [ index ] ! ;
544- var currentTemplate = GetBindableLayoutTemplate ( child ) ;
545- if ( currentTemplate == template )
556+ var child = ( IView ) layoutChildren [ index ] ! ;
557+ if ( child is BindableObject bindable && GetBindableLayoutTemplate ( bindable ) == template )
546558 {
547- child . BindingContext = item ;
559+ bindable . BindingContext = item ;
548560 }
549561 else
550562 {
551563 // It's our responsibility to clear the BindingContext for the children
552564 // Given that we've set them manually in CreateItemView
553- child . BindingContext = null ;
554565 layout . Replace ( CreateItemView ( item , template ) , index ) ;
566+ child . DisconnectHandlers ( ) ;
567+ ClearBindingContext ( child ) ;
555568 }
556569 }
557570
@@ -562,5 +575,14 @@ static View CreateItemView(object item, DataTemplate dataTemplate)
562575 view . BindingContext = item ;
563576 return view ;
564577 }
578+
579+
580+ static void ClearBindingContext ( IView child )
581+ {
582+ if ( child is BindableObject bindable && bindable . IsSet ( BindableLayoutTemplateProperty ) )
583+ {
584+ bindable . ClearValue ( BindableObject . BindingContextProperty ) ;
585+ }
586+ }
565587 }
566588}
0 commit comments