2
2
using System ;
3
3
using System . Collections ;
4
4
using System . Collections . Specialized ;
5
+ using System . Linq ;
5
6
using Microsoft . Maui . Controls . Internals ;
6
7
7
8
namespace Microsoft . Maui . Controls
@@ -371,6 +372,7 @@ void CreateChildren()
371
372
if ( childrenCount == 1 && layoutChildren [ 0 ] == _currentEmptyView )
372
373
{
373
374
layout . RemoveAt ( 0 ) ;
375
+ _currentEmptyView . DisconnectHandlers ( ) ;
374
376
childrenCount = 0 ;
375
377
}
376
378
@@ -394,11 +396,15 @@ void CreateChildren()
394
396
// Remove exceeding items
395
397
while ( index <= -- childrenCount )
396
398
{
397
- var child = ( BindableObject ) layoutChildren [ childrenCount ] ! ;
399
+ IView child = ( IView ) layoutChildren [ childrenCount ] ! ;
398
400
layout . RemoveAt ( childrenCount ) ;
401
+
402
+ // Disconnect platform view so when we clear binding context it doesn't run mappers
403
+ child . DisconnectHandlers ( ) ;
404
+
399
405
// It's our responsibility to clear the BindingContext for the children
400
406
// Given that we've set them manually in CreateItemView
401
- child . BindingContext = null ;
407
+ ClearBindingContext ( child ) ;
402
408
}
403
409
}
404
410
@@ -413,7 +419,7 @@ bool TryAddEmptyView(IBindableLayout layout, out IEnumerator enumerator)
413
419
// We may have a single child that is either the old empty view or a generated item
414
420
if ( layoutChildren . Count == 1 )
415
421
{
416
- var maybeEmptyView = ( View ) layoutChildren [ 0 ] ! ;
422
+ var maybeEmptyView = ( IView ) layoutChildren [ 0 ] ! ;
417
423
418
424
// If the current empty view is already in place we have nothing to do
419
425
if ( maybeEmptyView == _currentEmptyView )
@@ -425,11 +431,10 @@ bool TryAddEmptyView(IBindableLayout layout, out IEnumerator enumerator)
425
431
// So remove it to make room for the new empty view
426
432
layout . RemoveAt ( 0 ) ;
427
433
434
+ // Disconnect platform view so when we clear binding context it doesn't run mappers
435
+ maybeEmptyView . DisconnectHandlers ( ) ;
428
436
// 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 ) ;
433
438
}
434
439
else if ( layoutChildren . Count > 1 )
435
440
{
@@ -452,14 +457,19 @@ bool TryAddEmptyView(IBindableLayout layout, out IEnumerator enumerator)
452
457
453
458
void ClearChildren ( IBindableLayout layout )
454
459
{
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 )
457
464
{
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 ( ) ;
460
467
461
468
// 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
+ }
463
473
}
464
474
}
465
475
@@ -515,18 +525,21 @@ void ItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArg
515
525
if ( layoutChildren . Count == 1 && layoutChildren [ 0 ] == _currentEmptyView )
516
526
{
517
527
layout . RemoveAt ( 0 ) ;
528
+ _currentEmptyView . DisconnectHandlers ( ) ;
518
529
}
519
530
520
531
layout . Insert ( CreateItemView ( item , SelectTemplate ( item , layout ) ) , index ) ;
521
532
} ,
522
533
removeAt : ( item , index ) =>
523
534
{
524
- var child = ( View ) layout . Children [ index ] ! ;
535
+ var child = ( IView ) layout . Children [ index ] ! ;
525
536
layout . RemoveAt ( index ) ;
526
537
538
+ // Disconnect platform view so when we clear binding context it doesn't run mappers
539
+ child . DisconnectHandlers ( ) ;
527
540
// It's our responsibility to clear the BindingContext for the children
528
541
// Given that we've set them manually in CreateItemView
529
- child . BindingContext = null ;
542
+ ClearBindingContext ( child ) ;
530
543
531
544
// If we removed the last item, we need to insert the empty view
532
545
if ( layout . Children . Count == 0 && _currentEmptyView != null )
@@ -540,18 +553,18 @@ void ItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArg
540
553
void ReplaceChild ( object item , IBindableLayout layout , IList layoutChildren , int index )
541
554
{
542
555
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 )
546
558
{
547
- child . BindingContext = item ;
559
+ bindable . BindingContext = item ;
548
560
}
549
561
else
550
562
{
551
563
// It's our responsibility to clear the BindingContext for the children
552
564
// Given that we've set them manually in CreateItemView
553
- child . BindingContext = null ;
554
565
layout . Replace ( CreateItemView ( item , template ) , index ) ;
566
+ child . DisconnectHandlers ( ) ;
567
+ ClearBindingContext ( child ) ;
555
568
}
556
569
}
557
570
@@ -562,5 +575,14 @@ static View CreateItemView(object item, DataTemplate dataTemplate)
562
575
view . BindingContext = item ;
563
576
return view ;
564
577
}
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
+ }
565
587
}
566
588
}
0 commit comments