.Net MAUIの「AppShell.xaml」を利用してヘッダーのカスタマイズ方法を紹介していきます。当記事では、個別にカスタマイズする方法・共有にカスタマイズする方法を紹介していきます。
紹介環境
当記事では、以下のの環境を利用しています。
- Visual Studio 2022
- .Net 8
はじめに
当記事で利用する「AppShell.xaml」は、以下のように「App.xaml.cs」で「MainPage」にAppShellクラスを指定する必要があります。指定されていない場合、当記事の内容が利用できないため気をつけてください。
// 名前空間はプロジェクトごとに変わります。
namespace SampleApp;
public partial class App : Application
{
public App()
{
InitializeComponent();
// ↓ ここでAppShellを指定します
MainPage = new AppShell();
}
}
「AppShell.xaml」の詳細を知りたい方は、Microsoftで紹介されていますのでご確認ください。「AppShell.xaml」は、「Shell」を継承したコントロールになります。
.Net MAUIのヘッダーについて
.Net MAUIのヘッダーは、以下のように「ContentPage」のTitleプロパティの内容が表示されます。※「ContentPage」のTitleプロパティが未指定の場合、「AppShell.xaml」で指定されたTitleプロパティが反映されます。
<?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="SampleApp.Pages.Sample1"
Title="サンプル">
<VerticalStackLayout>
<Label
Text="ようこそ.Net MAUIへ!!"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentPage>
見た目は以下のようになります。
ヘッダーをカスタマイズする方法について
ヘッダーをカスタマイズするには、以下のように「Shell.TitleView」を利用します。
<Shell.TitleView>
<!-- ヘッダーの内容が入ります。 -->
</Shell.TitleView>
「Shell.TitleView」の利用する場所によってページ別か全ページか選択できます。
カスタマイズを個別にする場合
ヘッダーのカスタマイズを個別にする場合、以下のように「ContentPage」に対して「Shell.TitleView」を利用します。
<?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="SampleApp.Pages.Sample1">
<!-- ヘッダーのカスタマイズ -->
<!-- ここから -->
<Shell.TitleView>
<HorizontalStackLayout>
<Label
Text="サンプル"></Label>
<Button Text="クリック"></Button>
</HorizontalStackLayout>
</Shell.TitleView>
<!-- ここまで -->
<VerticalStackLayout>
<Label
Text="ようこそ.Net MAUIへ!!"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentPage>
見た目は以下のようになります。
カスタマイズを共有する場合
ヘッダーのカスタマイズを共有する場合、以下のように「AppShell.xaml(Shell)」に対して「Shell.TitleView」を利用します。
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="SampleApp.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SampleApp"
xmlns:pages="clr-namespace:SampleApp.Pages"
Shell.FlyoutBehavior="Disabled">
<!-- ヘッダーのカスタマイズ -->
<!-- ここから -->
<Shell.TitleView>
<HorizontalStackLayout>
<Label
Text="サンプル"></Label>
<Button Text="クリック"></Button>
</HorizontalStackLayout>
</Shell.TitleView>
<!-- ここまで -->
<ShellContent
Title="Sample1"
ContentTemplate="{DataTemplate pages:Sample1}"
Route="Sample1" />
</Shell>
見た目は以下のようになります。
優先順位について
ヘッダーのカスタマイズには、優先順位が存在します。最も優先されるのは、個別のカスタマイズになります。
実際に試した例は、次のようになります。
以下のように「ContentPage」と「AppShell.xaml(Shell)」を用意します。
<?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="SampleApp.Pages.Sample1">
<!-- ヘッダーのカスタマイズ -->
<!-- ここから -->
<Shell.TitleView>
<HorizontalStackLayout>
<Label
Text="サンプル(ContentPage)"></Label>
<Button Text="クリック"></Button>
</HorizontalStackLayout>
</Shell.TitleView>
<!-- ここまで -->
<VerticalStackLayout>
<Label
Text="ようこそ.Net MAUIへ!!"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentPage>
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="SampleApp.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SampleApp"
xmlns:pages="clr-namespace:SampleApp.Pages"
Shell.FlyoutBehavior="Disabled">
<!-- ヘッダーのカスタマイズ -->
<!-- ここから -->
<Shell.TitleView>
<HorizontalStackLayout>
<Label
Text="サンプル(AppShell)"></Label>
<Button Text="クリック"></Button>
</HorizontalStackLayout>
</Shell.TitleView>
<!-- ここまで -->
<ShellContent
Title="Sample1"
ContentTemplate="{DataTemplate pages:Sample1}"
Route="Sample1" />
</Shell>
見た目は以下のようになります。「サンプル(ContentPage)」が表示されているため、個別が優先されています。
Titleプロパティを反映する方法について
Titleプロパティが存在する要素(ContentPage・Shell)のTitleプロパティを「Label」に反映していきます。反映する方法は、2種類存在します。
Bindingを利用する場合
Bindingを利用する場合は、以下のように実装します。
Titleプロパティが存在する要素(ContentPage・Shell)のNameプロパティを指定します。
次に「Label」のTextプロパティにBindingでTitleを指定します。
実装してみた例が以下のようになります。例では「ContentPage」を利用しています。
<?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="SampleApp.Pages.Sample1"
x:Name="contentPage"
Title="サンプル">
<Shell.TitleView>
<HorizontalStackLayout>
<Label
BindingContext="{x:Reference contentPage}"
Text="{Binding Title}"></Label>
<Button Text="クリック"></Button>
</HorizontalStackLayout>
</Shell.TitleView>
<VerticalStackLayout>
<Label
Text="ようこそ.Net MAUIへ!!"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentPage>
この方法は共有でも利用できますが、「AppShell.xaml(Shell)」のTitleプロパティで利用すると全ページのタイトルが同じにになってしまいます。そのため、個別で利用する方が向いています。
「AppShell.xaml(Shell)」のイベントを利用する場合
「AppShell.xaml(Shell)」のイベントを利用する場合は、以下のように実装します。
Titleプロパティを反映したい要素のNameプロパティを指定します。以下の例では「Label」のNameプロパティを指定しています。
AppShellクラスに以下の内容を追加します。Titleプロパティの指定個所は複数あるため優先順位を決めています。この方法では「ContentPage > ShellContent > Shell」の順になっています。つまり、「ContentPage」が一番優先されます。
protected override void OnNavigated(ShellNavigatedEventArgs args)
{
base.OnNavigated(args);
/*
* 以下の優先順位でタイトルが指定されます。
* ContentPage > ShellContent > Shell
*/
label_title.Text = CurrentPage.Title ?? Current.CurrentItem?.Title ?? Title;
}
実装してみた例が以下のようになります。
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="SampleApp.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SampleApp"
xmlns:pages="clr-namespace:SampleApp.Pages"
Shell.FlyoutBehavior="Disabled">
<Shell.TitleView>
<HorizontalStackLayout>
<Label x:Name="label_title"></Label>
<Button Text="クリック"></Button>
</HorizontalStackLayout>
</Shell.TitleView>
<ShellContent
Title="Sample1"
ContentTemplate="{DataTemplate pages:Sample1}"
Route="Sample1" />
</Shell>
namespace SampleApp;
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
}
protected override void OnNavigated(ShellNavigatedEventArgs args)
{
base.OnNavigated(args);
label_title.Text = CurrentPage.Title ?? Current.CurrentItem?.Title ?? Title;
}
}
この方法では、「AppShell.xaml(Shell)」の画面遷移時イベントを利用します。そのため、共有で利用できる方法になっています。
終わりに
ヘッダーのカスタマイズに「Shell.TitleView」を利用してみました。「Shell.TitleView」を利用することで、様々なヘッダーを作成できますので利用してみてください。