nikita_97_10 nikita_97_10 - 3 months ago 58
C# Question

Add controller to all pages UWP

How to add an UI controller to all pages of the app? For example, having the same SplitView controller with navigation menu in Pane on all pages without copying its xaml code? Or maybe changing App.xaml in some way?

Or, as a second option, is it possible to create a UserControl that contains SplitView and put all other views on this page inside it Content? I mean, how to put views into the UserControl in xaml (or even in code)?

Answer

Create custom RootControl which derives from UserControl class and which contains the root Frame

    <SplitView DisplayMode="CompactOverlay">
      <SplitView.Pane>
        <StackPanel>
            <AppBarButton Icon="Home"
                          Width="50"
                          MinWidth="50"
                          Click="OnHomeClicked"
                          />
            <AppBarButton Icon="Shop"
                          Width="50"
                          MinWidth="50"
                          Click="OnShopClicked"/>
            <AppBarButton Icon="Setting"
                          MinWidth="50"
                          Width="50"
                          Click="OnSettingsClicked"/>
        </StackPanel>
      </SplitView.Pane>
      <SplitView.Content>
        <Grid>
            <Frame x:Name="rootFrame"/>

            <!--Put your hamburger button here-->

        </Grid>
      </SplitView.Content>
    </SplitView>

Rewrite OnLauched:

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {

        var rootControl = Window.Current.Content as RootControl;

        if (rootControl == null)
        {
            // Create a Frame to act as the navigation context and navigate to the first page
            rootControl = new RootControl();

            rootControl.RootFrame.NavigationFailed += OnNavigationFailed;

            if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
            {
                //TODO: Load state from previously suspended application
            }

            // Place the frame in the current Window
            Window.Current.Content = rootControl;
        }

        if (rootControl.RootFrame.Content == null)
        {
            // When the navigation stack isn't restored navigate to the first page,
            // configuring the new page by passing required information as a navigation
            // parameter
            rootControl.RootFrame.Navigate(typeof(MainPage), e.Arguments);
        }
        // Ensure the current window is active
        Window.Current.Activate();
    }

and you can manage you actions from code-behind or ViewModel for navigation and other actions

    public sealed partial class RootControl : UserControl
    {
        private Type currentPage;

        public RootControl()
        {
            this.InitializeComponent();
            RootFrame.Navigated += OnNavigated;
        }

        private void OnNavigated(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
        {
            currentPage = e.SourcePageType;
        }

        public Frame RootFrame
        {
            get
            {
                return rootFrame;
             }
        }

        private void OnHomeClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            Navigate(typeof(MainPage));
        }

        private void OnShopClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
             Navigate(typeof(StorePage));
        }

        private void OnSettingsClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
             Navigate(typeof(SettingsPage));
        }

        private void Navigate(Type pageSourceType)
        {
            if (currentPage != pageSourceType)
            {
                RootFrame.Navigate(pageSourceType);
            }
        }
    }

Download the sample and look how it works