jo phul
jo phul

Reputation: 647

Xamarin Forms - How to display content from one xaml inside another

I'm used to Android development, and am having some difficulty accomplishing what I would think is a simple task.

I have a MasterDetailPage (called ContainerView.xaml).

The Master is my navigation bar (called NavbarView.xaml).

The Details is supposed to be a page with a fixed title bar, and a "view" I can can swap per user choices.

The Details page is called MainView.xaml.

The Title I'd like to display at the top and is called TitleBarView.xaml.

Then I have a number of content pages such as Page1View.xaml.

in my ContainerView.xaml:

<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"             
                  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"       
                  x:Class="MyApp.ContainerView"
                  IsGestureEnabled="True"
                  MasterBehavior="Popover"
                  Title="MasterDetail Page">
  <MasterDetailPage.Master>
  </MasterDetailPage.Master>
  <MasterDetailPage.Detail>
  </MasterDetailPage.Detail>  
</MasterDetailPage>

in my NavbarView.xaml - this is the Master

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             x:Class="MyApp.NavBarView"
             Title="Nav Bar">  
  <ContentPage.Content>  
    <StackLayout Orientation="Vertical">
      <Label Text="{Binding Item1}"/>
      <Button Text="Options" Command="{Binding Option1Command}"/>
    </StackLayout >
  </ContentPage.Content>  
</ContentPage>

in my MainView.xaml - this is the details

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.MainView"
             Title="Main View">
  <ContentPage.Content>
  // what to put here to show the TitleBarView.xaml?
  // what to put here to show my content xaml pages?
  </ContentPage.Content>
</ContentPage>

in my TitleBarView.xaml

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.TitleBarView">
  <ContentView.Content>    
    <StackLayout Orientation="Horizontal">
      <Label Text="{Binding Item1}"/>
      <Button Text="Options" Command="{Binding OptionsCommand}"/>
    </StackLayout>    
  </ContentView.Content>
</ContentView>

and a generic content view, of course there will be many others I want to switch between

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.Page1View">
  <ContentView.Content>
    <StackLayout Orientation="Vertical">
      <Label Text="{Binding Info}"/>
      <Button Text="Log In" Command="{Binding GoToPage2Command}"/>
    </StackLayout >
  </ContentView.Content>
</ContentView>

I am using the MVVM model and have this code, but can't seem to get just the basics working. The Master page displays fine. If the Details page is just a simple page, it works, but I can't figure out how to insert the TitleBar and swap out the "Content".

ContainerView containerPage = new ContainerView(); 
ContainerViewModel containerVM = new ContainerViewModel();
containerPage.BindingContext = containerVM;

NavBarView navigationBar = new NavBarView();
navigationBar.Title = "Navigation Bar"; // required, otherwise I get an exception.
NavBarViewModel navigationBarVM = new NavBarViewModel();
navigationBar.BindingContext = navigationBarVM;

MainView mainView = new MainView();
mainView.Title = "MainView";
MainViewModel mainViewVM = new MainViewModel();
mainView.BindingContext = mainViewVM;

TitleBarView titleBar = new TitleBarView();
TitleBarViewModel titleBarVM = new TitleBarViewModel();
titleBar.BindingContext = titleBarVM;

Page1View page1 = new Page1View();
Page1ViewModel page1VM = new Page1ViewModel();
page1.BindingContext = page1VM;

mainView.Content = new StackLayout()
{
    Orientation = StackOrientation.Vertical,
    Children = 
    {
        new Label { Text = "I'm Content!" },
        new Label { Text = "I'm Content!" },
        //titleBar.Content,
        //loginView.Content
    }
};

containerPage.MasterBehavior = MasterBehavior.Popover;
containerPage.Master = navigationBar;
containerPage.Detail = new NavigationPage(mainView);

I'm sure I'm missing a fundamental concept. Any help would be appreciated

Upvotes: 1

Views: 3859

Answers (1)

Stephane Delcroix
Stephane Delcroix

Reputation: 16222

Xaml can instantiate any control, defined in code or in Xaml, so in case of TitleBarView, you can instantiate it in any Xaml by

<xmlnsprefix:TitleBarView />

The problem is to set the right xmlnsprefix. Every xaml file define a few xmlns and you can add your own, like this:

xmlns:local="clr-namespace:MyApp"

and it'll mean that the Xml namespace 'local' will reference the clr namespace 'MyApp' in the current assembly.

So you MainView becomes:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
   xmlns:local="clr-namespace:MyApp"
   x:Class="MyApp.MainView"
   Title="Main View">
  <ContentPage.Content>
   <local:TitleBarView />
  </ContentPage.Content>
</ContentPage>

Upvotes: 4

Related Questions