@@ -514,4 +514,70 @@ await Wait.For(async () =>
514514
515515 recorder . Success ( ) ;
516516 }
517+
518+ [ Test ]
519+ [ Description ( "Issue 4027" ) ]
520+ [ Arguments ( "" , new [ ] { Key . Tab } ) ]
521+ [ Arguments ( "" , new [ ] { Key . LeftShift , Key . Tab } ) ]
522+ [ Arguments ( "MaterialDesignEmbeddedDialogHost" , new [ ] { Key . Tab } ) ]
523+ [ Arguments ( "MaterialDesignEmbeddedDialogHost" , new [ ] { Key . LeftShift , Key . Tab } ) ]
524+ public async Task DialogHost_TrapsFocusInsidePopup_WhenTabbing ( string dialogHostStyle , Key [ ] inputActions )
525+ {
526+ await using var recorder = new TestRecorder ( App ) ;
527+
528+ var dialogHost = await LoadXaml < DialogHost > ( """
529+ <materialDesign:DialogHost>
530+ <Grid>
531+ <StackPanel>
532+ <TextBox />
533+ <Button x:Name="btnOpenDialog"
534+ Content="Open dialog"
535+ Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}" />
536+ </StackPanel>
537+ </Grid>
538+
539+ <materialDesign:DialogHost.DialogContent>
540+ <StackPanel Width="300">
541+ <TextBox x:Name="TextBoxOne" />
542+ <TextBox x:Name="TextBoxTwo" />
543+ </StackPanel>
544+ </materialDesign:DialogHost.DialogContent>
545+ </materialDesign:DialogHost>
546+ """ ) ;
547+
548+ if ( ! string . IsNullOrEmpty ( dialogHostStyle ) )
549+ {
550+ await dialogHost . RemoteExecute ( SetDialogHostStyle , dialogHostStyle ) ;
551+ }
552+
553+ var openDialogButton = await dialogHost . GetElement < Button > ( "btnOpenDialog" ) ;
554+ var textBoxOne = await dialogHost . GetElement < TextBox > ( "TextBoxOne" ) ;
555+ var textBoxTwo = await dialogHost . GetElement < TextBox > ( "TextBoxTwo" ) ;
556+
557+ await openDialogButton . LeftClick ( ) ;
558+
559+ await Task . Delay ( 400 , TestContext . Current ! . CancellationToken ) ;
560+
561+ // By default the first focusable element should be focused
562+ await Assert . That ( await textBoxOne . GetIsFocused ( ) ) . IsTrue ( ) ;
563+
564+ await textBoxOne . SendInput ( new KeyboardInput ( inputActions ) ) ;
565+ await Task . Delay ( 100 , TestContext . Current ! . CancellationToken ) ;
566+
567+ await Assert . That ( await textBoxTwo . GetIsFocused ( ) ) . IsTrue ( ) ;
568+
569+ await textBoxTwo . SendInput ( new KeyboardInput ( inputActions ) ) ;
570+ await Task . Delay ( 100 , TestContext . Current ! . CancellationToken ) ;
571+
572+ await Assert . That ( await textBoxOne . GetIsFocused ( ) ) . IsTrue ( ) ;
573+
574+ recorder . Success ( ) ;
575+
576+ static object SetDialogHostStyle ( DialogHost dialogHost , string styleName )
577+ {
578+ var style = ( Style ) dialogHost . FindResource ( styleName ) ;
579+ dialogHost . Style = style ;
580+ return null ! ;
581+ }
582+ }
517583}
0 commit comments