UWP NavigationView navigation via MVVM

Viewed 5578

I am using as main control in my app NavigationView and have Frame where page is loading.

<NavigationView x:Name="MyNavView" IsBackButtonVisible="Collapsed" SelectionChanged="{x:Bind ViewModel.OnSelectionChanged}" PaneDisplayMode="Top">
    <NavigationView.MenuItems>
        <NavigationViewItem Icon="Contact" Content="Contact" Tag="MasterDetailPage"/>
        <NavigationViewItem Icon="Favorite" Content="Favorites" Tag="FavoritesPage"/>
    </NavigationView.MenuItems>
    <Frame x:Name="RootFrame"/>
</NavigationView>

There are two events SelectionChanged and ItemInvoked that make available to realise navigation to pages that loading in RootFrame (name of my frame). But I want to use Command to make MVVM. And I have not found Command prop even for NavigationView itself or for NavigationViewItem. After that I have handled SelectionChanged event in ViewModel but at my view it contradicts MVVM.

So,how can I make MVVM using Command? If there is no such opportunity tell how to realise MVVM itself not handling event.

3 Answers

Implementing this is very similar to how you do it for WPF, you need to start by installing the Microsoft.Xaml.Behaviors.Uwp.Managed package via NuGet. Then you add a behavior to your NavigationView:

xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"

<NavigationView MenuItemsSource="{x:Bind ViewModel.MenuItems}">

    <i:Interaction.Behaviors>
        <core:EventTriggerBehavior EventName="ItemInvoked">
            <core:EventTriggerBehavior.Actions>
                <core:InvokeCommandAction Command="{x:Bind ViewModel.ItemInvokedCommand}" />
            </core:EventTriggerBehavior.Actions>
        </core:EventTriggerBehavior>
    </i:Interaction.Behaviors>

I'm using x:Bind here for compile-time error checking but a regular Binding will work just as well of course. Either way, follow this up with a command handler in your view model just as you would for WPF:

private ICommand _ItemInvokedCommand;
public ICommand ItemInvokedCommand => this._ItemInvokedCommand ?? (this._ItemInvokedCommand = new RelayCommand<NavigationViewItemInvokedEventArgs>(OnItemInvoked));


private void OnItemInvoked(NavigationViewItemInvokedEventArgs args)
{
    // could also use a converter on the command parameter if you don't like
    // the idea of passing in a NavigationViewItemInvokedEventArgs
    this.NavigationService.NavigateTo(args.InvokedItem);

In order to see how to properly use the NavigationView control (including the Data Binding case), please refer to the companion app called XAML Controls Gallery, available in the Windows Store, by Microsoft.

Best regards

Related