0

Hi I have a xaml File where I have a NavigationView with NavigatioViewItems. Inside the NavigationView I have a ScrollViewer where I want to inject a view. This is the xaml:

<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>

So far I have a NavigationService where I can navigate to different views:

    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, Type injectPage)
        {
            var frame = (Frame)Window.Current.Content;
            
            var page = frame.CurrentSourcePageType;
        }
    }

The NavigatScrollViewer method should implement this in a generic way because the whole app will use it. I will have different Windows like the xaml file above where I want to inject views into the ScrollViewer Frame. Is there a way to get a reference to this ScrollViewer inside code and then setting its Frame to the view I want to specify through the NavigationService? Any help is appreciated. Thanks

Florent
  • 111
  • 10
  • Please check the following, does it work? – Nico Zhu Jun 24 '21 at 09:49
  • Yes it works basically but the Binding seems not to work although I have a OnPropertyChange trigger in the setter. Refer to this question of mine where I asked how to attach different Commands to different MenuItems. In the answer you can see how I solved it. In the OnItemInvoked Method I dont use the NavigationService anymore I just set my property with the corresponding view type. When I debug it I can see that the binded property changes but it doesnt reflect on the UI. https://stackoverflow.com/questions/68102232/c-sharp-xaml-set-commands-for-different-menuitems-inside-a-navigationview – Florent Jun 24 '21 at 10:54
  • 1
    Ok solved: Needed to use Mode=TwoWay. Silly me is going to read now what these things mean... – Florent Jun 24 '21 at 11:13

1 Answers1

1

C# UWP MVVM inject a view inside another view

If you have used MVVM design, you need to bind Frame SourcePageType property with ViewModel's page type property. you just need to update this page type property, the Frame content will be update.

Here is sample code that you could refer.

Is there a way to get a reference to this ScrollViewer inside code and then setting its Frame to the view I want to specify through the NavigationService?

the other way is pass ContentFrame instance to NavigationService. At first you need add new frame property for NavigationService class. And then replace your code frame with MyFrame.

public class NavigationService
{
    private Frame MyFrame { get; set; }
    public NavigationService(Frame frame)
    {
        MyFrame = frame;
    }
}

Usgae

 var navService = new NavigationService(ContentFrame);

For above design is referring Windows Template Studio NavigationService, it is complete implementation, and you could find the NavigationService initialization process in the shell page.

ViewModel.Initialize(shellFrame, navigationView, KeyboardAccelerators);
Nico Zhu
  • 32,367
  • 2
  • 15
  • 36
  • 1
    You are the best! This was literally the last puzzle piece that I had to figure out. Works like a charm! – Florent Jun 24 '21 at 10:13