Florent
Florent

Reputation: 137

C# XAML Set Commands for different MenuItems inside a NavigationView

I have a xaml file where I set up a NavigationView with MenuItems. Inside my Project I implemented a basic Navigationservice which lets me switch the frames on Command Trigger:

Navigationservice:

    public class NavigationService : INavigationService
    {
        public void GoBack()
        {
            var frame = (Frame)Window.Current.Content;
            frame.GoBack();
        }

        public void Navigate(Type sourcePage)
        {
            var frame = (Frame)Window.Current.Content;
            frame.Navigate(sourcePage);    
        }

        public void Navigate(Type sourcePage, object parameter)
        {
            var frame = (Frame)Window.Current.Content;
            frame.Navigate(sourcePage, parameter);
        }

        public void NavigateScrollViewer(Type sourcePage)
        {
            //ToDo Inject sourcePage into ScrollViewer of Frame
            var frame = (Frame)Window.Current.Content;
            var page = frame.CurrentSourcePageType;
        }
    }

Now an example Command would be this: The RelayCommand is a basic implementation that you find all over the place.

        private ICommand _navigateToTextToSpeechView;

        public ICommand NavigateToTextToSpeechView
        {
            get 
            {
                return _navigateToTextToSpeechView =
                    new RelayCommand((a) =>
                    {
                        _navigationService.Navigate(typeof(AudioTextToSpeechView));
                        //ScrollFrame.Navigate(typeof(AudioHomeViewModel));
                    });
            }
        }

Further on I assign the ViewModel inside the code behind file of the view through the DataContext.

<Page
    x:Class="ToolBoxApp.Views.AudioHomeView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ToolBoxApp.Views"
    xmlns:viewmodels="using:ToolBoxApp.ViewModels"
    xmlns:mainview="clr-namespace:ToolBoxApp"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:i="using:Microsoft.Xaml.Interactivity"
    xmlns:core="using:Microsoft.Xaml.Interactions.Core"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <!--<Page.DataContext>
        <viewmodels:AudioHomeViewModel/>
    </Page.DataContext>-->
    
    <Grid>
        <NavigationView x:Name="navigationViewControl" 
                        IsBackEnabled="true">

            <i:Interaction.Behaviors>
                <core:EventTriggerBehavior EventName="ItemInvoked">
                    <core:EventTriggerBehavior.Actions>
                        <core:InvokeCommandAction Command="{Binding NavigateToTextToSpeechView}" />
                    </core:EventTriggerBehavior.Actions>
                </core:EventTriggerBehavior>
            </i:Interaction.Behaviors>

            <NavigationView.MenuItems>
                <NavigationViewItem Icon="MusicInfo" Content="Text to Speech"/>
                <NavigationViewItem Icon="MusicInfo" Content="Youtube to Mp3"/>
            </NavigationView.MenuItems>

            <ScrollViewer>
                <Frame x:Name="ContentFrame"/>
            </ScrollViewer>
    
        </NavigationView>
    </Grid>
</Page>

Now I found an answer to how to assign a command to the MenuItems thorugh the Microsoft.Xaml.Behaviors.Uwp.Managed NuGet package but the command gets now triggered for all MenuItems which I dont want. I want to assign different Commands to different MenuItems. How would I be able to achieve this?

Upvotes: 0

Views: 137

Answers (1)

Florent
Florent

Reputation: 137

I solved it like this:

        public ICommand NavigateToTextToSpeechView
        {
            get 
            {
                return _navigateToTextToSpeechView =
                    new GenericRelayCommand<NavigationViewItemInvokedEventArgs>(OnItemInvoked);
            }
        }

        public void OnItemInvoked(NavigationViewItemInvokedEventArgs args)
        {
            string invokedItemName = args.InvokedItem.ToString();
            Debug.WriteLine(invokedItemName);

            if (invokedItemName.Equals("Text to Speech"))
            {
                _navigationService.Navigate(typeof(AudioTextToSpeechView));
            }
        }

Personally I dont like this approach but it works. Just if someone is interested. If someone coould provide a better solution without string checks than I would be happy. In the long run this function could become pretty big depending on how much NavigationMenuItems I have.

Upvotes: 1

Related Questions