Throughout the development of my app, I found that many pages will have a very similar content to one another, with only one difference amongst them. In order to prevent duplicated code and, consequently, more maintenance, I decided to make all of them inherit from a single base page.
However, no matter what I did, the content would always be displayed incorrectly. Instead of showing the content of both the base page and the child page, only the child page would be displayed.
I made a test project to keep experimenting until I found a solution, but to no avail. Here's what I have so far:
Base Page .xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage"
Title="MainPage">
<VerticalStackLayout>
<!-- The child page will need access to this label as well -->
<Label x:Name="LabelMain" Text="MainPage content."/>
<!-- This is where the child page's content should be -->
<ContentPresenter/>
</VerticalStackLayout>
</ContentPage>
Base Page .cs:
namespace MauiApp1
{
public partial class MainPage : ContentPage
{
// The child will need access to this variable.
protected int test = 0;
public MainPage()
{
InitializeComponent();
}
}
}
Child Page .xaml:
<?xml version="1.0" encoding="utf-8" ?>
<local:MainPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiApp1"
x:Class="MauiApp1.NewPage1"
Title="NewPage1">
<Label Text="NewPage1 content."/>
</local:MainPage>
Child Page .cs:
namespace MauiApp1;
public partial class NewPage1 : MainPage
{
public NewPage1()
{
InitializeComponent();
}
}
The Result: the child page's content overriding the base page
As you can see, the child page (NewPage1) has completely overridden the base page's (MainPage) content.
My question is: how can I make the content of both pages be displayed in the manner that I desire, which is the child page replacing only the designated <ContentPresenter/>
tag?
EDIT: Forgot to mention that the child page will require access to the base page's views and variables too.
Here's how to implement a reusable BasePage
with a custom property
<!-- BasePage.xaml -->
<ContentPage
x:Class="MyMauiDemo.BasePage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<ContentView.ControlTemplate>
<ControlTemplate>
<VerticalStackLayout>
<Label Text="{TemplateBinding MainText}" />
<ContentPresenter />
</VerticalStackLayout>
</ControlTemplate>
</ContentView.ControlTemplate>
</ContentView>
// BasePage.xaml.cs
namespace MyMauiDemo;
public partial class BasePage: ContentPage
{
public static readonly BindableProperty MainTextProperty = BindableProperty.Create(nameof(MainText), typeof(string), typeof(BasePage), default(string));
public string MainText
{
get => (string)GetValue(MainTextProperty);
set => SetValue(MainTextProperty, value);
}
public BasePage()
{
InitializeComponent();
}
}
And here's how you can use BasePage
:
<!-- MainPage.xaml -->
<local:BasePage
x:Class="MyMauiDemo.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyMauiDemo"
TitlePage="MainPage"
MainText="HELLO WORLD">
<Label Text="MainPage content." />
</local:BasePage>
References: