My exact problem is I am trying to add logic to all the pages in my Xamarin app, globally.
That is, I am trying to create a "master page" that all my pages inherit from. I put header/footer and navigation logic in this "master page" so that I don't have to rewrite it on every page. ...I say "master page" because Xamarin has something called a master-detail page and that's not what I'm talking about. I'm talking about the concept of a master page like you might have used in ASP.NET Web Forms. The closest analog to that in Xamarin is <ControlTemplate>
which, with a little work on your part, gives pretty much the same effect as what you might actually think of as a master page. It kind of looks like this:
App.xaml (the body of the master page)
...
<Application.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="MainPageTemplate">
<StackLayout>
<Label Text="{TemplateBinding HeaderText}" />
<ContentPresenter /> <!-- this is a placeholder for content -->
<Label Text="{TemplateBinding FooterText}" />
</StackLayout>
</ControlTemplate>
</ResourceDictionary>
</Application.Resources>
...
MyPage.xaml (the content that goes in the master page)
<!-- Translation: this page inherits from CoolApp.Views.MyMasterPage.cs -->
<Views:MyMasterPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:Views="clr-namespace:CoolApp.Views"
x:Class="CoolApp.Views.MyPage"
ControlTemplate="{StaticResource MainPageTemplate}">
<Label Text="I am the content" />
</Views:MyMasterPage>
MyMasterPage.cs (the shared header/footer and navigation logic)
// it inherits from ContentPage here, which works fine. so long as your app only uses ContentPages
public class MyMasterPage : ContentPage, INotifyPropertyChanged
{
...
public static BindableProperty HeaderTextProperty;
public string HeaderText
{
get { return (string)GetValue(HeaderTextProperty); }
set
{
HeaderTextProperty = BindableProperty.Create("HeaderText", typeof(string), typeof(SearchPage), value);
OnPropertyChanged("HeaderText");
}
}
// footer logic
// navigation logic
...
}
This master page setup works great for me until I need to use page types other than ContentPage
. Specifically, I need a CarouselPage
to work exactly the same way. In the above code I could have MyMasterPage.cs
inherit from CarouselPage
instead of ContentPage
and that would be fine except then I would have the global header/footer and navigation logic in two different master pages. I can't just put the logic in a master page that inherits from Page
because then my pages would be of type Page
instead of ContentPage
and CarouselPage
. But if I could modify Page
directly then ContentPage
and CarouselPage
would both get my changes. Maybe that would sort of look like this?
I hope it's clear but in case it's not the question I am trying to ask is how can I get my header and footer and navigation logic all into a single master page?