How to display content from one xaml inside another

CaseCase USMember ✭✭

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

Best Answer

Answers

  • requenaxiirequenaxii USMember

    Thanks @AlexDunn, it's a very easy way (I need to put more attention on my XAML skills).

    I have a question from that, I use the native navigation bar on my project and change between ContentViews through a CustomTabLayout in order to use the same design on Android and iOS but, I don't know how to change the Title when I switch between Views.

    I hope you can give me an approach. Thanks.

  • Rohit_ArnavRohit_Arnav USMember ✭✭

    @requenaxii
    public static readonly BindableProperty HeaderTextProperty = BindableProperty.Create("HeaderText", typeof(string), typeof(HomePage), "Home Page");
    public string HeaderText
    {
    get { return (string)GetValue(HeaderTextProperty); }
    }

    use this in your all content page and change the "Home Page" with what u want your title..

  • JassimRahmaJassimRahma USMember ✭✭✭

    I tried that but did not not @AlexDunn

    My Main page is:

    <?xml version="1.0" encoding="UTF-8"?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="Zeera.ZeeraPage"
        ControlTemplate="{StaticResource MainPageTemplate}"
        xmlns:views="Zeera.MyPage">
        <ContentPage.Content>
            <StackLayout HorizontalOptions="Center" VerticalOptions="StartAndExpand">
                <Label Text="tems Items Items Items Items Items Items Items  " />
            </StackLayout>
            <views:MyPage />
        </ContentPage.Content>
    </ContentPage>
    

    and the page I want to put inside the main page is:

    <?xml version="1.0" encoding="UTF-8"?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="Zeera.MyPage">
        <ContentPage.Content>
        </ContentPage.Content>
    </ContentPage>
    

    Kindly help...

    Thanks,
    Jassim

  • CaseCase USMember ✭✭

    @JassimRahma You can't put a ContentPage inside of a ContentPage. Make what you want to insert a ContentView and it should work.

    What I do in my apps is have a single MainPage that is a content page, and make all my "pages" actually be ContentViews. Then just swap out the content as I navigate.

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="MyApp.Views.MainPage">
    
        <ContentPage.Content>
    
            <AbsoluteLayout HorizontalOptions="FillAndExpand" 
                            VerticalOptions="FillAndExpand"
                            BackgroundColor="LightGray">
    
                <ContentView x:Name="Container" 
                             HorizontalOptions="FillAndExpand" 
                             VerticalOptions="FillAndExpand" 
                             AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                             AbsoluteLayout.LayoutFlags="All" />
    
                <ActivityIndicator IsVisible="{Binding IsBusy}" 
                                   IsRunning="{Binding IsBusy}" 
                                   IsEnabled="True" 
                                   Color="Black" 
                                   AbsoluteLayout.LayoutBounds="0.5, 0.5, 0.5, 0.5"
                                   AbsoluteLayout.LayoutFlags="All" />
    
            </AbsoluteLayout>
    
        </ContentPage.Content>
    
    </ContentPage>
    
    
    public NavigationController()
    {
        ContainerPage = new MainPage();
    }
    
    protected ViewModel currentViewModel = null;
    
    protected ContentPage _ContainerPage;
    public ContentPage ContainerPage
    {
        get { return _ContainerPage; }
        set
        {
            if (value != _ContainerPage)
            {
                _ContainerPage = value;
            }
        }
    }
    
    protected View _Content;
    public View Content
    {
        protected get { return _Content; }
        set
        {
            if (value != _Content)
            {
                _Content = value;
                ContainerPage.FindByName<ContentView>("Container").Content = value;
            }
        }
    }
    
    public void SetContent(Type vType)
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            ContentView content = (ContentView)Activator.CreateInstance(vType);
            currentViewModel = (ViewModel)content.BindingContext;
            Content = content;
        });
    }
    
  • JassimRahmaJassimRahma USMember ✭✭✭

    I removed the ContentPage but still having trouble..

    <?xml version="1.0" encoding="utf-8" ?>
    <StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="Zeera.MyPage"
    Orientation="Horizontal"
    HorizontalOptions="FillAndExpand" Padding="10" BackgroundColor="White">
    <Button Text="Internal 1"  />
    <Button Text="Internal 2"  />
    </StackLayout>
    
    
    using System;
    using System.Collections.Generic;
    
    using Xamarin.Forms;
    
    namespace Zeera
    {
        public partial class MyPage: StackLayout
        {
            public MyPage()
            {
                InitializeComponent();
            }
        }
    }
    
Sign In or Register to comment.