0

I have a navigation view at the left side of my app, works ok. I would like to add another control like that to the right.

I did not find any way to position the control like that so, is it a feasible solution to put another control and apply a transform matrix in order to mirror it at the right?

Currently I have a stackpanel with a collection of vertical button but I like the navigation view more.

Michael Chourdakis
  • 10,345
  • 3
  • 42
  • 78

2 Answers2

1

One way to do this is to re-style NavigationView.

Bring the default Style for NavigationView from the generic.xaml. Make sure that the version matches your WindowsAppSDK's version.

The minimal changes you need to make:

  • Set the HorizontalAlignment to Right on the PaneToggleButtonGrid.
  • Set the PanePlacement to Right on the RootSplitView.
  • Set the HorizontalAlignment to Right on the PaneContentGrid.
<?xml version="1.0" encoding="utf-8" ?>
<Page
    x:Class="RightNavigationViewExample.ShellPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="using:Microsoft.UI.Xaml.Controls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:RightNavigationViewExample"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    mc:Ignorable="d">
    <Page.Resources>
        <Style
            x:Key="RightNavigationViewStyle"
            TargetType="controls:NavigationView">
            <Setter Property="PaneToggleButtonStyle" Value="{StaticResource PaneToggleButtonStyle}" />
            <Setter Property="IsTabStop" Value="False" />
            <Setter Property="CompactPaneLength" Value="{ThemeResource NavigationViewCompactPaneLength}" />
            <Setter Property="CornerRadius" Value="{ThemeResource OverlayCornerRadius}" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="controls:NavigationView">
                        <Grid x:Name="RootGrid">
                            <!--  Button grid  -->
                            <Grid
                                x:Name="PaneToggleButtonGrid"
                                Width="48"
                                HorizontalAlignment="Right"
                                VerticalAlignment="Top"
                                Canvas.ZIndex="100">

                                <!--  ABBREVIATED  -->

                                <!--  Displaymode (compact/minimal/normal) left  -->
                                <SplitView
                                    x:Name="RootSplitView"
                                    Grid.Row="1"
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="{ThemeResource NavigationViewItemSeparatorForeground}"
                                    BorderThickness="{ThemeResource NavigationViewBorderThickness}"
                                    CompactPaneLength="{TemplateBinding CompactPaneLength}"
                                    CornerRadius="{Binding Source={ThemeResource OverlayCornerRadius}, Converter={StaticResource RightCornerRadiusFilterConverter}}"
                                    DisplayMode="Inline"
                                    IsPaneOpen="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsPaneOpen, Mode=TwoWay}"
                                    IsTabStop="False"
                                    OpenPaneLength="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.OpenPaneWidth}"
                                    PaneBackground="{ThemeResource NavigationViewDefaultPaneBackground}"
                                    PanePlacement="Right">
                                    <SplitView.Pane>
                                        <Grid
                                            x:Name="PaneContentGrid"
                                            Margin="{ThemeResource NavigationViewPaneContentGridMargin}"
                                            HorizontalAlignment="Right"
                                            BorderBrush="{ThemeResource NavigationViewItemSeparatorForeground}"
                                            Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.LeftPaneVisibility}">
                                    <!--  ABBREVIATED  -->

                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Page.Resources>

    <!--  RightNavigationView  -->
    <Grid>
        <NavigationView
            SelectionChanged="NavigationView_SelectionChanged"
            Style="{StaticResource RightNavigationViewStyle}">
            <NavigationView.MenuItems>
                <NavigationViewItem
                    Content="Home"
                    Tag="RightNavigationViewExample.HomePage">
                    <NavigationViewItem.MenuItems>
                        <NavigationViewItem
                            Content="Page A"
                            Tag="RightNavigationViewExample.PageA" />
                    </NavigationViewItem.MenuItems>
                </NavigationViewItem>
            </NavigationView.MenuItems>
            <Frame x:Name="ContentFrame" />
        </NavigationView>
    </Grid>
</Page>
Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21
1

Another way to do this, with less code, is by getting the target items and changing the properties directly.

You can get the target items using the VisualTreeHelper but it's easier using the CommunityToolkit.WinUI.UI NuGet package.

First, name your NavigationView control, e.g. RightNavigationViewControl.

<NavigationView
    x:Name="RightNavigationViewControl"
    SelectionChanged="NavigationView_SelectionChanged">
    <NavigationView.MenuItems>
        <NavigationViewItem
            Content="Home"
            Icon="Home"
            Tag="RightNavigationViewExample.HomePage">
            <NavigationViewItem.MenuItems>
                <NavigationViewItem
                    Content="Page A"
                    Tag="RightNavigationViewExample.PageA" />
            </NavigationViewItem.MenuItems>
        </NavigationViewItem>
    </NavigationView.MenuItems>
    <Frame x:Name="ContentFrame" />
</NavigationView>

Then get the target items using the FindDescendant extension method from the CommunityToolkit.WinUI.UI and change the properties like this:

using CommunityToolkit.WinUI.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;

namespace RightNavigationViewExample;

public sealed partial class ShellPage : Page
{
    public ShellPage()
    {
        this.InitializeComponent();
        this.RightNavigationViewControl.Loaded += RightNavigationViewControl_Loaded;
    }

    private void RightNavigationViewControl_Loaded(object sender, RoutedEventArgs e)
    {
        if (this.RightNavigationViewControl.FindDescendant<Grid>(x => x.Name is "PaneToggleButtonGrid") is Grid paneToggleButtonGrid &&
            this.RightNavigationViewControl.FindDescendant<SplitView>(x => x.Name is "RootSplitView") is SplitView rootSplitView &&
            this.RightNavigationViewControl.FindDescendant<Grid>(x => x.Name is "PaneContentGrid") is Grid paneContentGrid)
        {
            paneToggleButtonGrid.HorizontalAlignment = HorizontalAlignment.Right;
            rootSplitView.PanePlacement = SplitViewPanePlacement.Right;
            paneContentGrid.HorizontalAlignment = HorizontalAlignment.Right;
        }
    }
}
Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21