0
votes

I'm struggling to create the UI I have in my head and to date have been fairly unsuccessful.

I'm trying to create a Main Page which hosts my NavView and inside of by NavView I wish to have a command bar which will control which NavViewItems are visible. I have created a quick image of what I'm trying to achieve.

In my example I have the home button in the command bar activated which displays

  • Nav Item Header
  • Navigation Item 1
  • etc...

enter image description here

I want to be able to click documents and have the indicator switch to documents and hide the navigation items corresponding to Home and show the navigation items corresponding to Documents.

Finally, I want the command bar to collapse when the NavView pane is compact but the user should be able to click the Command bar button and expand the command bar to change between Home, Documents etc.

Really looking for any help/advice for the best places to start.

I'm still learning the UWP controls and Xaml.

3

3 Answers

1
votes

I think you should use a SplitView instead of NavigationView outside, and then, inside the Pane of the Splitview, use a NavigationView with some trick to achieve what you desired.

Key points are:

  1. Keep the NavigationView's PaneDisplayMode LeftComact
  2. don't use the PaneToggleButton in the NavigationView to prevent user from changing PaneDisplayMode by clicking it, use a custom one instead to open and close pane.
  3. Change the PaneDisplayMode of the NavigationView to Top when pane opens, and backt to LeftComact again when pane closes.

Here is what I have achieved with NavigationView inside Splitview.Pane:

enter image description here

You can decorate it and make it more visually satisfying, like adding an AutoSuggestBox or Setting button, but that's the basic. Btw, don't use the NavigationView's Setting button, as I have seen it behaving strangely here.

XAML:

<SplitView 
    x:Name="Split"
    DisplayMode="CompactInline"
    CompactPaneLength="40">
    <SplitView.Pane>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition />
            </Grid.RowDefinitions>

            <Button
                Click="Button_Click">
                <SymbolIcon Symbol="List"/>
            </Button>

            <NavigationView 
                Grid.Row="1"
                x:Name="NavView"
                PaneDisplayMode="LeftCompact"
                CompactPaneLength="{x:Bind Split.CompactPaneLength}"
                IsBackButtonVisible="Collapsed"
                IsPaneToggleButtonVisible="False"
                IsSettingsVisible="False"
                SelectionChanged="NavView_SelectionChanged">
                <NavigationView.MenuItems>
                    <NavigationViewItem x:Name="HomeItem" Icon="Home" VerticalAlignment="Stretch"/>
                    <NavigationViewItem x:Name="DocumentItem" Icon="Document" />
                    <NavigationViewItem x:Name="PeopleItem" Icon="People" />
                </NavigationView.MenuItems>

                <ContentControl>
                    <ListView 
                        x:Name="ItemList"/>
                </ContentControl>

            </NavigationView>

        </Grid>
    </SplitView.Pane>
</SplitView>

Code behind:

public sealed partial class MainPage : Page
{
    public List<string> HomeItemList;
    public List<string> DocumentItemList;
    public List<string> PeopleItemList;

    public MainPage()
    {
        InitializeComponent();

        HomeItemList = new List<string> { "HomeItem1", "HomeItem2", "HomeItem3" };
        DocumentItemList = new List<string> { "DocumentItem1", "DocumentItem2", "DocumentItem3" };
        PeopleItemList = new List<string> { "PeopleItem1", "PeopleItem2", "PeopleItem3" };
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Split.IsPaneOpen = !Split.IsPaneOpen;
        if (Split.IsPaneOpen)
        {
            NavView.PaneDisplayMode = NavigationViewPaneDisplayMode.Top;
        }
        else NavView.PaneDisplayMode = NavigationViewPaneDisplayMode.LeftCompact;
    }

    private void NavView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
    {
        if (args.SelectedItem != null)
        {
            Split.IsPaneOpen = true;
            NavView.PaneDisplayMode = NavigationViewPaneDisplayMode.Top;

            if (sender.SelectedItem == HomeItem)
                ItemList.ItemsSource = HomeItemList;
            else if(sender.SelectedItem == DocumentItem)
                ItemList.ItemsSource = DocumentItemList;
            else if(sender.SelectedItem == PeopleItem)
                ItemList.ItemsSource = PeopleItemList;
        }
    }
}

Hope that helps.

1
votes

First thing is to decide if you want to use NavigationView. In XAML controls are defined by their behavior (properties and methods that they implement), while the visual appearance is irrelevant and can be altered completely. If NavigationView is right for your task then you can alter its style partially or completely - in XAML editor right click on it, then click Edit Template > Edit a Copy. Now you'll get the XAML style definition that defines appearance of NavigationView, that's the place to start.

But it might be very well that you can't use NavigationView and that starting with SplitView might be a better idea as @Muzib said.

Not sure if this is a good idea for learning XAML, but you'll learn one thing - XAML can be customized to the great extent, but doing it may also be a very complex task.

0
votes

I think there are a few problems from the UX perspective.

  1. Not all the navigation items are shown at once and a used must expand the menu to change between the sets of items.
  2. The positions of the navigation items changes when the navigation pane is expanded. Currently the way the control works it is though the pane is expanding to show the text of the button. With your suggested approach it would like the items jump down on open.

I wonder if would be easier to have a fixed side pane with the controls laid out like you want and no hamburger button etc. This is not so unusual, the Settings app does it.

If you do go with a fixed width pane, I recommend looking at the XAML that defines the NavigationView control, which can be found inside C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.17763.0\Generic\generic.xaml (according to the version of your SDK). Then you can make sure to use the theme resources used by the Windows so that your custom control has a similar look and feel.