Root FlyoutPage

A FlyoutPage has a Flyout property that should be set to a ContentPage containing the content of the flyout (or a NavigationPage, once this bug has been fixed) and a Detail property for the remaining content.

As usual, create and register the following:

  • A ContentPage and ViewModel to be presented in the Flyout's Flyout

  • Any and all ContentPage and ViewModel classes that may be presented for the Flyout.Detail

Assuming the Flyout property is represented using a FlyoutFlyoutPage bound to a FlyoutFlyoutPageVm, we set our MainPage like this:

namespace SampleFlyoutApp
{
    public partial class App : Application
    {
        public App(IPageServiceZero pageService)
        {
            InitializeComponent();
            
            // Don't forget to call pageService.Init, or navigation will not work properly!
            pageService.Init(this);

            MainPage = pageService.GetFlyoutPage<FlyoutFlyoutPageVm>();
        }
    }
}

Now we need a way to manage the Detail property of the Flyout. This is achieved using

_pageService.FlyoutController.SetDetailVm<TViewModel>(bool wrapInNavigation, Action initViewModelAction, object hint=null)

Here's an example that sets the default view when the page is first presented, and has ICommands to swap between two different detail pages. These pages are wrapped in a NavigationPage, so they in turn can push pages onto their own navigation stack

namespace SampleFlyoutApp.Mvvm.PageViewModels.Root
{
    public class FlyoutFlyoutPageVm : MvvmZeroBasePageVm
    {
        private readonly IPageServiceZero _pageService;

        public ICommand Test1Command { get; }       
        public ICommand Test2Command { get; }

        public FlyoutFlyoutPageVm(IPageServiceZero pageService)
        {
            _pageService = pageService;

            _pageService.FlyoutController.FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
            
            Test1Command = new CommandBuilder().AddGuard(this).SetName("Test1").SetExecuteAsync(Test1CommandExecuteAsync).Build();
            Test2Command = new CommandBuilder().AddGuard(this).SetName("Test2").SetExecuteAsync(Test2CommandExecuteAsync).Build();
        }
        
        private async Task Test1CommandExecuteAsync()
        {
            _pageService.FlyoutController.SetDetailVm<Test1PageVm>(true, vm => { });
        }        
        private async Task Test2CommandExecuteAsync()
        {
          _pageService.FlyoutController.SetDetailVm<Test2PageVm>(true, vm => { });        }
        }
        
        public override void OnOwnerPageAppearing()
        {
            base.OnOwnerPageAppearing();
            // Set a default Page when the FlyoutFlyoutPage is first presented ...
            _pageService.FlyoutController.SetDetailVm<DefaultFlyoutPageVm>(true, vm => { });
        }
    }
}

Now just add two Buttons to FlyoutFlyoutPage.xaml and bind them to Test1Command and Test2Command to swap the Detail view on button click

Take a look at the SampleFlyoutApp source code to see an example of a Flyout containing a tree-structure of options, each one tied to a different Detail page

Last updated