@@ -577,5 +577,206 @@ public void InitialNavigationDoesntSetQueryAttributesProperty()
577577 _ = new TestShell ( content ) ;
578578 Assert . False ( content . IsSet ( ShellContent . QueryAttributesProperty ) ) ;
579579 }
580+
581+ // Tests for Issue #13537 - TabBar navigation should invoke ApplyQueryAttributes
582+ // These tests verify that QueryAttributesProperty is set on ShellContent when switching tabs,
583+ // which triggers ApplyQueryAttributes on the page/viewmodel implementing IQueryAttributable.
584+
585+ [ Fact ]
586+ public async Task TabBarNavigationSetsQueryAttributesProperty ( )
587+ {
588+ // Arrange: Create a TabBar with two tabs
589+ var testPage1 = new ShellTestPage ( ) ;
590+ var testPage2 = new ShellTestPage ( ) ;
591+
592+ var content1 = new ShellContent { Content = testPage1 , Route = "content1" } ;
593+ var content2 = new ShellContent { Content = testPage2 , Route = "content2" } ;
594+
595+ var tab1 = new Tab { Title = "Tab1" , Route = "tab1" } ;
596+ tab1 . Items . Add ( content1 ) ;
597+
598+ var tab2 = new Tab { Title = "Tab2" , Route = "tab2" } ;
599+ tab2 . Items . Add ( content2 ) ;
600+
601+ var tabBar = new TabBar ( ) ;
602+ tabBar . Items . Add ( tab1 ) ;
603+ tabBar . Items . Add ( tab2 ) ;
604+
605+ var shell = new TestShell ( ) ;
606+ shell . Items . Add ( tabBar ) ;
607+
608+ // Verify initial state - QueryAttributesProperty not set on tab2's content
609+ Assert . False ( content2 . IsSet ( ShellContent . QueryAttributesProperty ) ,
610+ "QueryAttributesProperty should not be set initially" ) ;
611+
612+ // Act: Switch to the second tab
613+ tabBar . CurrentItem = tab2 ;
614+ await Task . Yield ( ) ;
615+
616+ // Assert: QueryAttributesProperty should now be set on tab2's content
617+ // This is what triggers ApplyQueryAttributes on the page
618+ Assert . True ( content2 . IsSet ( ShellContent . QueryAttributesProperty ) ,
619+ "QueryAttributesProperty should be set when switching tabs (Issue #13537)" ) ;
620+ }
621+
622+ [ Fact ]
623+ public async Task TabBarNavigationWithGoToAsyncSetsQueryAttributesProperty ( )
624+ {
625+ // Arrange: Create a TabBar with two tabs
626+ var testPage1 = new ShellTestPage ( ) ;
627+ var testPage2 = new ShellTestPage ( ) ;
628+
629+ var content1 = new ShellContent { Content = testPage1 , Route = "content1" } ;
630+ var content2 = new ShellContent { Content = testPage2 , Route = "content2" } ;
631+
632+ var tab1 = new Tab { Title = "Tab1" , Route = "tab1" } ;
633+ tab1 . Items . Add ( content1 ) ;
634+
635+ var tab2 = new Tab { Title = "Tab2" , Route = "tab2" } ;
636+ tab2 . Items . Add ( content2 ) ;
637+
638+ var tabBar = new TabBar ( ) ;
639+ tabBar . Items . Add ( tab1 ) ;
640+ tabBar . Items . Add ( tab2 ) ;
641+
642+ var shell = new TestShell ( ) ;
643+ shell . Items . Add ( tabBar ) ;
644+
645+ // Act: Navigate to tab2 using GoToAsync without parameters
646+ await shell . GoToAsync ( "///tab2/content2" ) ;
647+
648+ // Assert: QueryAttributesProperty should be set
649+ Assert . True ( content2 . IsSet ( ShellContent . QueryAttributesProperty ) ,
650+ "QueryAttributesProperty should be set when navigating via GoToAsync (Issue #13537)" ) ;
651+ }
652+
653+ // Tests for Issue #28453 - ShellContent routes should call ApplyQueryAttributes
654+ [ Fact ]
655+ public async Task FlyoutItemNavigationSetsQueryAttributesProperty ( )
656+ {
657+ // Arrange: Create Shell with two FlyoutItems
658+ var testPage1 = new ShellTestPage ( ) ;
659+ var testPage2 = new ShellTestPage ( ) ;
660+
661+ var flyoutItem1 = CreateShellItem < FlyoutItem > ( testPage1 , shellItemRoute : "flyout1" ) ;
662+ var flyoutItem2 = CreateShellItem < FlyoutItem > ( testPage2 , shellItemRoute : "flyout2" ) ;
663+
664+ var shell = new TestShell ( flyoutItem1 , flyoutItem2 ) ;
665+
666+ // Get the ShellContent for flyoutItem2
667+ var content2 = flyoutItem2 . CurrentItem . CurrentItem ;
668+
669+ // Verify initial state
670+ Assert . False ( content2 . IsSet ( ShellContent . QueryAttributesProperty ) ,
671+ "QueryAttributesProperty should not be set initially" ) ;
672+
673+ // Act: Navigate to the second flyout item
674+ IShellController shellController = shell ;
675+ await shellController . OnFlyoutItemSelectedAsync ( flyoutItem2 ) ;
676+
677+ // Assert: QueryAttributesProperty should now be set
678+ Assert . True ( content2 . IsSet ( ShellContent . QueryAttributesProperty ) ,
679+ "QueryAttributesProperty should be set when switching FlyoutItems (Issue #28453)" ) ;
680+ }
681+
682+ [ Fact ]
683+ public async Task NavigatingBackToTabSetsQueryAttributesProperty ( )
684+ {
685+ // Arrange: Create a TabBar with two tabs
686+ var testPage1 = new ShellTestPage ( ) ;
687+ var testPage2 = new ShellTestPage ( ) ;
688+
689+ var content1 = new ShellContent { Content = testPage1 , Route = "content1" } ;
690+ var content2 = new ShellContent { Content = testPage2 , Route = "content2" } ;
691+
692+ var tab1 = new Tab { Title = "Tab1" , Route = "tab1" } ;
693+ tab1 . Items . Add ( content1 ) ;
694+
695+ var tab2 = new Tab { Title = "Tab2" , Route = "tab2" } ;
696+ tab2 . Items . Add ( content2 ) ;
697+
698+ var tabBar = new TabBar ( ) ;
699+ tabBar . Items . Add ( tab1 ) ;
700+ tabBar . Items . Add ( tab2 ) ;
701+
702+ var shell = new TestShell ( ) ;
703+ shell . Items . Add ( tabBar ) ;
704+
705+ // Act: Navigate tab1 -> tab2 -> tab1
706+ tabBar . CurrentItem = tab2 ;
707+ await Task . Yield ( ) ;
708+
709+ Assert . True ( content2 . IsSet ( ShellContent . QueryAttributesProperty ) ,
710+ "QueryAttributesProperty should be set when switching to tab2" ) ;
711+
712+ tabBar . CurrentItem = tab1 ;
713+ await Task . Yield ( ) ;
714+
715+ // Assert: QueryAttributesProperty should be set on tab1 when navigating back
716+ Assert . True ( content1 . IsSet ( ShellContent . QueryAttributesProperty ) ,
717+ "QueryAttributesProperty should be set when switching back to tab1" ) ;
718+ }
719+
720+ [ Fact ]
721+ public async Task PopNavigationTriggersApplyQueryAttributes ( )
722+ {
723+ // Arrange
724+ var shell = new TestShell ( CreateShellItem ( ) ) ;
725+ Routing . RegisterRoute ( "details" , typeof ( ShellTestPage ) ) ;
726+
727+ // Navigate to details page with parameter
728+ await shell . GoToAsync ( $ "details?{ nameof ( ShellTestPage . SomeQueryParameter ) } =1234") ;
729+ var detailsPage = shell . CurrentPage as ShellTestPage ;
730+ Assert . Equal ( "1234" , detailsPage . SomeQueryParameter ) ;
731+
732+ // Navigate to another page
733+ await shell . GoToAsync ( "details" ) ;
734+ var secondPage = shell . CurrentPage as ShellTestPage ;
735+
736+ // Act: Pop back
737+ await shell . GoToAsync ( ".." ) ;
738+
739+ // Assert: ApplyQueryAttributes should have been called on the first details page
740+ // to restore its parameters
741+ Assert . True ( detailsPage . AppliedQueryAttributes . Count >= 2 ,
742+ "ApplyQueryAttributes should be triggered when popping back to a page" ) ;
743+ Assert . Equal ( "1234" , detailsPage . SomeQueryParameter ) ;
744+ }
745+
746+ [ Fact ]
747+ public async Task ShellSectionChangedSetsQueryAttributesProperty ( )
748+ {
749+ // Arrange: Create Shell with multiple sections in a single ShellItem
750+ var testPage1 = new ShellTestPage ( ) ;
751+ var testPage2 = new ShellTestPage ( ) ;
752+
753+ var content1 = new ShellContent { Content = testPage1 , Route = "content1" } ;
754+ var content2 = new ShellContent { Content = testPage2 , Route = "content2" } ;
755+
756+ var section1 = new ShellSection { Route = "section1" } ;
757+ section1 . Items . Add ( content1 ) ;
758+
759+ var section2 = new ShellSection { Route = "section2" } ;
760+ section2 . Items . Add ( content2 ) ;
761+
762+ var shellItem = new ShellItem { Route = "item" } ;
763+ shellItem . Items . Add ( section1 ) ;
764+ shellItem . Items . Add ( section2 ) ;
765+
766+ var shell = new TestShell ( ) ;
767+ shell . Items . Add ( shellItem ) ;
768+
769+ // Verify initial state
770+ Assert . False ( content2 . IsSet ( ShellContent . QueryAttributesProperty ) ,
771+ "QueryAttributesProperty should not be set initially" ) ;
772+
773+ // Act: Change the current section
774+ shellItem . CurrentItem = section2 ;
775+ await Task . Yield ( ) ;
776+
777+ // Assert: QueryAttributesProperty should be set
778+ Assert . True ( content2 . IsSet ( ShellContent . QueryAttributesProperty ) ,
779+ "QueryAttributesProperty should be set when changing ShellSection" ) ;
780+ }
580781 }
581782}
0 commit comments