Xamarin.Forms: Can I embed one ContentPage or ContentView into another ContentPage
Asked Answered
B

2

15

I have multiple ContentPage xaml files in my Xamarin project. I want to embed a shared piece of xaml into each ContentPage. There is nothing particularly special about the shared piece of xaml (it does't need to do anything platform specific). Shouldn't it be just as easy as embedding a tag in the xaml of the ContentPage to include the shared xaml file? Can someone point me in the right direction?

Beatnik answered 23/5, 2015 at 21:14 Comment(0)
M
15

You can take the parent child of your ContentPage (for example, a StackLayout that wraps all the children), put it in an external xaml file, and then include that component in each one of your ContentPages.

The external xaml file will be a StackLayout type, rather than a ContentPage.

Edit - added a code sample:

Let's add a header StackLayout: we add a code behind class:

public partial class HeaderNavigationBar 
{
    public HeaderNavigationBar()
    {
        InitializeComponent();
    }
}

Then add the XAML code:

<StackLayout x:Class="HeaderNavigationBar"
             Orientation="Horizontal"
             HorizontalOptions="FillAndExpand"
             Padding="10"
             BackgroundColor="White">

    <Image Source="burger_icon"
           HorizontalOptions="StartAndExpand"
           Aspect="AspectFit">
        <Image.GestureRecognizers>
            <TapGestureRecognizer Command="{Binding SlideNavigationDrawerCommand}" />
        </Image.GestureRecognizers>
    </Image>
</StackLayout>

And finally, in the page where you want to reuse your component - add this reference:<HeaderNavigationBar />.

Manchester answered 24/5, 2015 at 8:4 Comment(7)
Thank you. That will get me closer. Can you tell me what the syntax is for including that external xaml file into my content pages?Beatnik
Getting closer. When I try to run that, it gives me this error in the xaml file: "x is undeclared namespace." Any thoughts?Beatnik
You need to add to the Content Page header decelerations something like this: xmlns:common="clr-namespace:Consumer.Mobile.Views.Common;assembly=Consumer.Mobile" and then declare your reference like this: <common:HeaderNavigationBar></common:HeaderNavigationBar>Manchester
Still no luck. The contentpage errors out with "Type common:HeaderNavigation not found in xmlns clr-namespace..." etc.Beatnik
Is there no official documentation on this anywhere?Beatnik
Common is the namespace of the folder I have placed the header navigation bar. You should replace it with your namespace.Manchester
Thank you for the help. I was able to get it to work cross-platform as long as the XAML and code-behind files are in a Portable Class Library. Sadly in my case I was using a Shared Project so that I could also use Parse.com libraries in a shared scenario. If I move my Xamarin Forms code-behinds to a Portable Class Library, then that will break my Parse code since there's not a version of Parse available for PCL yet, that I know of. Anyway, thank you very much for the help in figuring out how to include a contentview into a contentpage!Beatnik
R
19

Thank you very much IdoT, It did work for me, but after adding some lines. As this will help in making templates/custom controls/sub forms, easily added/shared across Xamarin.Forms.

Here is my full work based on your suggestion, so it can be used as is with others:

HeaderNavigationBar.xaml

<?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="App9.MVC.Views.HeaderNavigationBar"
             Orientation="Horizontal"
             HorizontalOptions="FillAndExpand"
             Padding="10"
             ackgroundColor="White">

    <Button Text="Internal 1" />
    <Button Text="Internal 2" />
</StackLayout>

As you can see, added:

xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

and in the HeaderNavigationBar.cs, it was declared as StackLayout:

HeaderNavigationBar.cs

using Xamarin.Forms;

namespace App9.MVC.Views
{
    public partial class HeaderNavigationBar : StackLayout
    {
        public HeaderNavigationBar()
        {
            InitializeComponent();
        }
    }
}

then for the page that will hold it/show it:

MainView.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:common="clr-namespace:App9.MVC.Views;assembly=App9"
             x:Class="App9.MVC.Views.MainView">

    <StackLayout Padding="0,0,0,20">
        <common:HeaderNavigationBar>
            <Button Text="External 1" />
        </common:HeaderNavigationBar>

        <Button Text="Test Button 1
                x:Name="btnPage1"
                Clicked="btnPage1_clicked" />
    </StackLayout>
</ContentPage>

As you can notice, the namespace has the full path, in the MainView:

xmlns:common="clr-namespace:App9.MVC.Views;assembly=App9"

Also, you can notice that there is a button called External 1, this will also show with the Internal buttons, as the control is a StackLayout, so it can handle adding more controls.

Screenshot:

enter image description here

Also for Page inside another Page:

Again thanks goes to IdoT.

Rutland answered 3/5, 2016 at 19:39 Comment(0)
M
15

You can take the parent child of your ContentPage (for example, a StackLayout that wraps all the children), put it in an external xaml file, and then include that component in each one of your ContentPages.

The external xaml file will be a StackLayout type, rather than a ContentPage.

Edit - added a code sample:

Let's add a header StackLayout: we add a code behind class:

public partial class HeaderNavigationBar 
{
    public HeaderNavigationBar()
    {
        InitializeComponent();
    }
}

Then add the XAML code:

<StackLayout x:Class="HeaderNavigationBar"
             Orientation="Horizontal"
             HorizontalOptions="FillAndExpand"
             Padding="10"
             BackgroundColor="White">

    <Image Source="burger_icon"
           HorizontalOptions="StartAndExpand"
           Aspect="AspectFit">
        <Image.GestureRecognizers>
            <TapGestureRecognizer Command="{Binding SlideNavigationDrawerCommand}" />
        </Image.GestureRecognizers>
    </Image>
</StackLayout>

And finally, in the page where you want to reuse your component - add this reference:<HeaderNavigationBar />.

Manchester answered 24/5, 2015 at 8:4 Comment(7)
Thank you. That will get me closer. Can you tell me what the syntax is for including that external xaml file into my content pages?Beatnik
Getting closer. When I try to run that, it gives me this error in the xaml file: "x is undeclared namespace." Any thoughts?Beatnik
You need to add to the Content Page header decelerations something like this: xmlns:common="clr-namespace:Consumer.Mobile.Views.Common;assembly=Consumer.Mobile" and then declare your reference like this: <common:HeaderNavigationBar></common:HeaderNavigationBar>Manchester
Still no luck. The contentpage errors out with "Type common:HeaderNavigation not found in xmlns clr-namespace..." etc.Beatnik
Is there no official documentation on this anywhere?Beatnik
Common is the namespace of the folder I have placed the header navigation bar. You should replace it with your namespace.Manchester
Thank you for the help. I was able to get it to work cross-platform as long as the XAML and code-behind files are in a Portable Class Library. Sadly in my case I was using a Shared Project so that I could also use Parse.com libraries in a shared scenario. If I move my Xamarin Forms code-behinds to a Portable Class Library, then that will break my Parse code since there's not a version of Parse available for PCL yet, that I know of. Anyway, thank you very much for the help in figuring out how to include a contentview into a contentpage!Beatnik

© 2022 - 2024 — McMap. All rights reserved.