mrcstr
mrcstr

Reputation: 41

When opening a new page it overlapses the NavigationView menu

I made a basic app that has a menu with two options, each of them takes to a new page. The problem is that those pages are launched over the main one so it overlapses the menu and everything behind. Those pages don't have any content, their code is an simple xaml and xaml.cs.

I used some examples that Microsoft developer webpage gives, but the result is the same. I haven't found any other possible solution and I am not able to understand what is happening.

Page that contains the menu

<Grid>
  <NavigationView
    x:Name="NavView"
    ItemInvoked="NavViewItemInvoked"
    Windows10version1803:BackRequested="NavViewBackRequested"
    Windows10version1803:IsBackEnabled="{x:Bind Frame.CanGoBack, Mode=OneWay}"
  >
    <NavigationView.MenuItems>
      <NavigationViewItem x:Name="HomePage" Content="Home" Icon="Home" />
      <NavigationViewItem x:Name="AddPage" Content="Add" Icon="Add" />
    </NavigationView.MenuItems>

    <NavigationView.AutoSuggestBox>
      <AutoSuggestBox x:Name="SearchBox" QueryIcon="Find" />
    </NavigationView.AutoSuggestBox>

    <ScrollViewer>
      <frame x:Name="ContentFrame" Padding="12,0,12,24" IsTabStop="True" NavigationFailed="ContentFrame_NavigationFailed" />
    </ScrollViewer>
  </NavigationView>

  <frame x:Name="frame" Margin="20,0,0,0" Navigating="OnNavigatingToPage">
    <Frame.ContentTransitions>
      <TransitionCollection>
        <NavigationThemeTransition>
          <NavigationThemeTransition.DefaultNavigationTransitionInfo>
            <EntranceNavigationTransitionInfo />
          </NavigationThemeTransition.DefaultNavigationTransitionInfo>
        </NavigationThemeTransition>
      </TransitionCollection>
    </Frame.ContentTransitions>
  </frame>

  <VisualStateManager.VisualStateGroups>
    <VisualStateGroup>
      <VisualState>
        <VisualState.StateTriggers>
          <AdaptiveTrigger MinWindowWidth="{x:Bind NavView.CompactModeThresholdWidth}" />
        </VisualState.StateTriggers>
        <VisualState.Setters>
          <!-- Leave the next line for left-only navigation. -->
          <Setter Target="ContentFrame.Padding" Value="24,0,24,24" />
        </VisualState.Setters>
      </VisualState>
    </VisualStateGroup>
  </VisualStateManager.VisualStateGroups>
</Grid>

Function that opens the selected item in the menu:

    private void NavViewItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
    {
        var label = args.InvokedItem as string;
        var pageType =
            label == "Home" ? typeof(HomePage) :
            label == "Add" ? typeof(AddPage) : null;
        if (pageType != null && pageType != AppFrame.CurrentSourcePageType)
        {
            AppFrame.Navigate(pageType);
        }
    }

I hope someone could tell me what it's happening or where is the mistake.

Thanks a lot

Upvotes: 0

Views: 1738

Answers (2)

Pratyay
Pratyay

Reputation: 1301

From what I understood , your requirement is to have a navigation view which will use a frame to navigate between the different pages of the application.

I have simplified your solution a bit hopefully this should help. In the following solution I have used a single frame for the navigation.

XAML

<Grid>
    <NavigationView x:Name="NavView" ItemInvoked="NavViewItemInvoked">
        <NavigationView.MenuItems>
            <NavigationViewItem x:Name="HomePage" Content="Home" Icon="Home" />
            <NavigationViewItem x:Name="AddPage" Content="Add" Icon="Add" />
        </NavigationView.MenuItems>

        <NavigationView.AutoSuggestBox>
            <AutoSuggestBox x:Name="SearchBox" QueryIcon="Find" />
        </NavigationView.AutoSuggestBox>
        <!-- Removed scroll viewer not sure if this is required -->
        <Frame x:Name="ContentFrame" IsTabStop="True"
         NavigationFailed="ContentFrame_NavigationFailed" />            
    </NavigationView>
</Grid>

C#

private void NavViewItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
    {
        var label = args.InvokedItem as string;
        var pageType =
            label == "Home" ? typeof(HomePage) :
            label == "Add" ? typeof(AddPage) : null;
        if (pageType != null && pageType != ContentFrame.CurrentSourcePageType)
        {
            ContentFrame.Navigate(pageType);
        }
    }

enter image description here


Explanation :

As mentioned above, this solution has only one frame for the navigation. Whenever user selects an item in the Navigation View, it will navigate the ContentFrame to the desired page [ContentFrame.Navigate(pageType)]; .

Let me know if you require any more explanation or refer to Martin Zikmund's Answer

Upvotes: 2

Martin Zikmund
Martin Zikmund

Reputation: 39082

The structure of your UI looks like this

  • NavigationView
    • Frame (ContentFrame)
  • Frame (AppFrame)

The basic rule in XAML is that for content at the same level, what comes later in the code, is drawn above what comes before. Of course this is very simplified, as you can layout children of a panel in such way they don't overlap, but we are considering your particular case now.

The NavigationView and the second Frame are on the same level, and are both inside the root Grid, without any Grid.Column or Grid.Row attributes specified. In such case, the Frame is directly above the NavigationView. At first this does not matter much, as there is no content there and hence the Frame is "invisible". Once you actually navigate within the Frame however, the page will completely cover the NavigationView and that will in turn "disappear".

What I found confusing however, is that you have two Frame controls in your code. The one you should actually use is the one named as ContentFrame. This one is embedded in the NavigationView and that is the most common way to present pages. So if you remove the second Frame altogether and change all code to use ContentFrame instead, you should get the behavior you want.

Upvotes: 2

Related Questions