@@ -423,6 +423,80 @@ private Android.Widget.TimePicker FindTimePicker(Android.Views.View root)
423423#endif
424424#endif
425425
426+ [ TestMethod ]
427+ [ GitHubWorkItem ( "https://github.com/unoplatform/uno/issues/21958" ) ]
428+ public async Task When_Fast_Scrolling_Items_Should_Remain_Visible ( )
429+ {
430+ TimePicker timePicker = new ( )
431+ {
432+ Time = new TimeSpan ( 12 , 30 , 0 )
433+ } ;
434+ #if HAS_UNO
435+ timePicker . UseNativeStyle = false ;
436+ #endif
437+ TestServices . WindowHelper . WindowContent = timePicker ;
438+ await TestServices . WindowHelper . WaitForLoaded ( timePicker ) ;
439+
440+ await DateTimePickerHelper . OpenDateTimePicker ( timePicker ) ;
441+ await TestServices . WindowHelper . WaitForIdle ( ) ;
442+
443+ ( var hourLoopingSelector , _ , _ ) = await DateTimePickerHelper . GetHourMinutePeriodLoopingSelectorsFromOpenFlyout ( ) ;
444+
445+ Assert . IsNotNull ( hourLoopingSelector , "HourLoopingSelector should be found" ) ;
446+
447+ ScrollViewer scrollViewer = null ;
448+ LoopingSelectorPanel panel = null ;
449+ var initialRealizedItemCount = 0 ;
450+
451+ await TestServices . RunOnUIThread ( ( ) =>
452+ {
453+ scrollViewer = ( ScrollViewer ) VisualTreeUtils . FindVisualChildByName ( hourLoopingSelector , "ScrollViewer" ) ;
454+ Assert . IsNotNull ( scrollViewer , "ScrollViewer should be found" ) ;
455+
456+ panel = scrollViewer . Content as LoopingSelectorPanel ;
457+ Assert . IsNotNull ( panel , "LoopingSelectorPanel should be found" ) ;
458+
459+ initialRealizedItemCount = panel . Children . Count ;
460+ Assert . IsGreaterThan ( 0 , initialRealizedItemCount , "Should have realized items initially" ) ;
461+ } ) ;
462+
463+ // Simulate fast scrolling by rapidly changing the scroll position
464+ // This triggers multiple intermediate ViewChanged events
465+ var scrollPositions = new [ ] { 100.0 , 200.0 , 300.0 , 400.0 , 500.0 , 600.0 , 700.0 , 800.0 } ;
466+
467+ foreach ( var scrollPosition in scrollPositions )
468+ {
469+ await TestServices . RunOnUIThread ( ( ) =>
470+ {
471+ scrollViewer . ChangeView ( null , scrollPosition , null , disableAnimation : false ) ;
472+ } ) ;
473+
474+ await Task . Delay ( 10 ) ; // Small delay to allow event processing
475+
476+ var currentItemCount = 0 ;
477+ await TestServices . RunOnUIThread ( ( ) =>
478+ {
479+ currentItemCount = panel . Children . Count ;
480+ } ) ;
481+
482+ Assert . IsGreaterThan ( 0 ,
483+ currentItemCount , $ "Should have visible items during fast scrolling at position { scrollPosition } , but found { currentItemCount } items") ;
484+ }
485+
486+ await TestServices . WindowHelper . WaitForIdle ( ) ;
487+
488+ var finalRealizedItemCount = 0 ;
489+ await TestServices . RunOnUIThread ( ( ) =>
490+ {
491+ finalRealizedItemCount = panel . Children . Count ;
492+ } ) ;
493+
494+ Assert . IsGreaterThan ( 0 , finalRealizedItemCount , "Should have realized items after scrolling completes" ) ;
495+
496+ await ControlHelper . ClickFlyoutCloseButton ( timePicker , false /* isAccept */ ) ;
497+ await TestServices . WindowHelper . WaitForIdle ( ) ;
498+ }
499+
426500 class MyContext
427501 {
428502 public object StartTime => null ;
0 commit comments