Search code examples
c#maui

How can I create a BasePage in MAUI with sections?


In my .NET8 MAUI application, I have a lot of pages with the same XAML code and code behind. For example, I have the advertisement at the bottom of the XAML pages and use the same code to remove the space from the command line.

I found a lot of examples with the BasePage with C# code but none related to the XAML. What I like to do is to have only 1 BasePage where I manage the advertisement and then in the other pages add the content. For example:

<?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"
             xmlns:ads="clr-namespace:Plugin.MauiMTAdmob.Controls;assembly=Plugin.MauiMTAdmob"
             x:Class="LanguageInUse.Views.BasePage"
             Title="BasePage">

    <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <VerticalStackLayout x:Name="First"></VerticalStackLayout>
        <VerticalStackLayout x:Name="Second"></VerticalStackLayout>
    
        <VerticalStackLayout
            Grid.Row="2"
            Margin="0,5,0,0"
            BackgroundColor="AliceBlue"
            HorizontalOptions="FillAndExpand"
            VerticalOptions="FillAndExpand">
            <ads:MTAdView
                x:Name="ads"
                AdSize="AnchoredAdaptive"
                AdsId="{Binding AdsId}"
                IsVisible="true" />
        </VerticalStackLayout>
    </Grid>
</ContentPage>

So, in a page that inherits from BasePage, I like to add the XAML in the section First or Second. I'm not sure I can do that. Is there any example? Is it possible to do that?


Solution

  • Step 1 - Create BasePage using ControlTemplate and ContentPresenter:

    <ContentPage
      x:Class="MauiSamples.Views.BasePage"
      xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    
      <ContentPage.ControlTemplate>
        <ControlTemplate>
    
          <Grid RowDefinitions="250,*,250">
    
            <Label
              Grid.Row="0"
              FontSize="Title"
              HorizontalOptions="Center"
              Text="Header"
              VerticalOptions="Center" />
    
            <ContentPresenter Grid.Row="1" />
    
            <Label
              Grid.Row="2"
              FontSize="Title"
              HorizontalOptions="Center"
              Text="Footer"
              VerticalOptions="Center" />
    
          </Grid>
    
        </ControlTemplate>
      </ContentPage.ControlTemplate>
    
    </ContentPage>
    

    Step 2 - Use BasePage:

    Create a new page that inherits from BasePage and add content like you would for any other page or view:

    <views:BasePage
      x:Class="MauiSamples.Views.PageWithBase"
      xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
      xmlns:views="clr-namespace:MauiSamples.Views">
    
      <Grid>
        <Label
          FontSize="Title"
          HorizontalOptions="Center"
          Text="Hello from Page"
          VerticalOptions="Center" />
      </Grid>
    
    </views:BasePage>
    

    Note that the root must not be ContentPage but instead should be your BasePage.

    It's important that any page that uses your BasePage inherits also from BasePage in the code-behind:

    public partial class PageWithBase : BasePage
    {
        public PageWithBase()
        {
            InitializeComponent();
        }
    }
    

    Also note that you can only use a single <ContentPresenter /> instance per view or page that you want to use as a base. In all other cases, you need to define properties of type <ContentView />.

    You can see a working example in my MAUI samples repo.