Visual Studio で .NET MAUI プロジェクトを作成する

完了

.NET MAUI ツールをインストールして構成した後、Visual Studio を使用して .NET MAUI (Multi-platform Application User Interface) アプリを構築できます。

このユニットでは、Visual Studio の .NET MAUI テンプレートの構造について説明します。 このテンプレートは、クロスプラットフォームのモバイル アプリとデスクトップ アプリの作成に使用します。

ファースト ステップ

Visual Studio を使用して新しい .NET MAUI プロジェクトを作成するには、[新しいプロジェクトの作成] ダイアログ ボックスで .NET MAUI プロジェクトの種類を選択し、[.NET MAUI アプリ] テンプレートを選択します。

Visual Studio の [新しいプロジェクトの作成] ダイアログ ボックスのスクリーンショット。ユーザーは .NET MAUI アプリ テンプレートを選択します。

ウィザードの手順に従ってプロジェクトに名前を付け、場所を指定します。

新しく作成された .NET MAUI プロジェクトには、次のように項目が含まれています。

Visual Studio の新しい .NET MAUI ソリューションの既定の構造のソリューション エクスプローラーのスクリーンショット。

.NET MAUI プロジェクトの構造とアプリケーションの起動

プロジェクトの内容には、次の項目が含まれます。

  • App.xaml このファイルを使用して、アプリが XAML (Extensible Application Markup Language) レイアウトで使用するアプリケーション リソースを定義します。 既定のリソースは Resources フォルダー内にあり、.NET MAUI の組み込みコントロールごとにアプリ全体の色と既定のスタイルを定義します。 このように、2 つのリソース ディクショナリがマージされています。

    <?xml version = "1.0" encoding = "UTF-8" ?>
    <Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:MyMauiApp"
                 x:Class="MyMauiApp.App">
        <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="Resources/Colors.xaml" />
                    <ResourceDictionary Source="Resources/Styles.xaml" />
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Application.Resources>
    </Application>
    
  • App.xaml.cs このファイルは App.xaml ファイルの分離コードです。 App クラスが定義されています。 このクラスは、実行時のアプリケーションを表します。 このクラスのコンストラクターでは、初期ウィンドウを作成して MainPage プロパティに割り当てます。このプロパティにより、アプリケーションの実行を開始するときに表示されるページが決定されます。 さらに、このクラスを使用すると、一般的なプラットフォームに依存しないアプリケーション ライフサイクル イベント ハンドラーをオーバーライドできます。 イベントには、OnStartOnResumeOnSleep が含まれます。 これらのハンドラーは、Application 基底クラスのメンバーとして定義されます。 次のコードに例を示します。

    Note

    また、初めてアプリの実行が開始されるときに、プラットフォーム固有のライフサイクル イベントをオーバーライドすることもできます。 これについては後で説明します。

    namespace MyMauiApp;
    
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
    
            MainPage = new AppShell();
        }
    
        protected override void OnStart()
        {
            base.OnStart();
        }
    
        protected override void OnResume()
        {
            base.OnResume();
        }
    
        protected override void OnSleep()
        {
            base.OnSleep();
        }
    }
    
  • AppShell.xaml このファイルは、.NET MAUI アプリケーションのメイン構造です。 .NET MAUI Shell には、マルチプラットフォーム アプリに役立つ機能が多数あります。たとえば、アプリのスタイル設定、URI ベースのナビゲーション、レイアウトのオプション (ポップアップ ナビゲーションやアプリケーションのルートのタブなど) です。 既定のテンプレートには、アプリの起動時に拡大される 1 つのページ (または ShellContent) が用意されています。

      <?xml version="1.0" encoding="UTF-8" ?>
      <Shell
          x:Class="MyMauiApp.AppShell"
          xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
          xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
          xmlns:local="clr-namespace:MyMauiApp"
          Shell.FlyoutBehavior="Disabled">
    
          <ShellContent
              Title="Home"
              ContentTemplate="{DataTemplate local:MainPage}"
              Route="MainPage" />
    
      </Shell>
    
  • MainPage.xaml このファイルには、ユーザー インターフェイス定義が含まれています。 MAUI アプリ テンプレートによって生成されるサンプル アプリには、2 つのラベル、1 つのボタン、1 つのイメージが含まれています。 コントロールは、ScrollView で囲まれた VerticalStackLayout を使用して配置されます。 VerticalStackLayout 要素を使用すると、コントロールを垂直方向に (積み重ねた状態に) 整列できます。また、ScrollView を使用すると、ビューが大きすぎてデバイスに表示できない場合にスクロールバーを表示できます。 このファイルの内容を独自の UI レイアウトに置き換えることを目的としています。 マルチページ アプリがある場合は、さらに 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="MyMauiApp.MainPage">
    
        <ScrollView>
            <VerticalStackLayout 
                Spacing="25" 
                Padding="30,0" 
                VerticalOptions="Center">
    
                <Image
                    Source="dotnet_bot.png"
                    SemanticProperties.Description="Cute dot net bot waving hi to you!"
                    HeightRequest="200"
                    HorizontalOptions="Center" />
    
                <Label 
                    Text="Hello, World!"
                    SemanticProperties.HeadingLevel="Level1"
                    FontSize="32"
                    HorizontalOptions="Center" />
    
                <Label 
                    Text="Welcome to .NET Multi-platform App UI"
                    SemanticProperties.HeadingLevel="Level2"
                    SemanticProperties.Description="Welcome to dot net Multi platform App U I"
                    FontSize="18"
                    HorizontalOptions="Center" />
    
                <Button 
                    x:Name="CounterBtn"
                    Text="Click me"
                    SemanticProperties.Hint="Counts the number of times you click"
                    Clicked="OnCounterClicked"
                    HorizontalOptions="Center" />
    
            </VerticalStackLayout>
        </ScrollView>
    
    </ContentPage>
    
  • MainPage.xaml.cs このファイルには、ページの分離コードが含まれます。 このファイルでは、ページ上のコントロールによってトリガーされるさまざまなイベント ハンドラーとその他のアクションのロジックを定義します。 このコード例では、ページ上のボタンの Clicked イベントのハンドラーを実装しています。 このコードは、単にカウンター変数をインクリメントし、結果をページのラベルに表示するだけです。 MAUI Essentials ライブラリの一部として提供されるセマンティック サービスは、アクセシビリティをサポートしています。 SemanticScreenReader クラスの静的 Announce メソッドでは、ユーザーがボタンを選択したときにスクリーン リーダーによって通知されるテキストを指定します。

    namespace MyMauiApp;
    
    public partial class MainPage : ContentPage
    {
        int count = 0;
    
        public MainPage()
        {
            InitializeComponent();
        }
    
        private void OnCounterClicked(object sender, EventArgs e)
        {
            count++;
    
            if (count == 1)
                CounterBtn.Text = $"Clicked {count} time";
            else
                CounterBtn.Text = $"Clicked {count} times";
    
            SemanticScreenReader.Announce(CounterBtn.Text);
        }
    }
    
  • MauiProgram.cs 各ネイティブ プラットフォームには、アプリケーションを作成して初期化するさまざまな開始点があります。 このコードは、プロジェクトの Platforms フォルダー内にあります。 このコードはプラットフォーム固有ですが、最後に静的 MauiProgram クラスの CreateMauiApp メソッドを呼び出します。 この CreateMauiApp メソッドを使用して、アプリ ビルダー オブジェクトを作成してアプリケーションを構成します。 少なくとも、アプリ ビルダー オブジェクトの UseMauiApp ジェネリック メソッドを使用して、アプリケーションを記述するクラスを指定する必要があります。type パラメーター (<App>) にはアプリケーション クラスを指定します。 アプリ ビルダーには、フォントの登録、依存関係の挿入のためのサービスの構成、コントロールのカスタム ハンドラーの登録などのタスクのメソッドも用意されています。 次のコードは、アプリ ビルダーを使用してフォントを登録する例を示しています。

    namespace MyMauiApp;
    
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                });
    
            return builder.Build();
        }
    }
    
  • プラットフォーム このフォルダーには、プラットフォーム固有の初期化コード ファイルとリソースが含まれています。 Android、iOS、MacCatalyst、Tizen、Windows 用のフォルダーがあります。 実行時に、アプリはプラットフォーム固有の方法で起動します。 起動プロセスの大部分は MAUI ライブラリによって抽象化されますが、これらのフォルダー内のコード ファイルは、独自のカスタム初期化をフックするためのメカニズムを備えています。 重要な点は、初期化が完了すると、前に説明したように、プラットフォーム固有のコードにより MauiProgram.CreateMauiApp メソッドが呼び出され App オブジェクトが作成されて実行されることです。 たとえば、Android フォルダーの MainApplication.cs ファイル、iOS フォルダーと MacCatalyst フォルダーの AppDelegate.cs ファイル、Windows フォルダー内の App.xaml.cs ファイルには、すべてオーバーライドが含まれます。

    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
    

次の図は、.NET MAUI アプリの起動時の制御フローを示しています。

.NET MAUI アプリの起動時の制御フローの図。ネイティブ固有のスタートアップから、MAUI アプリの作成関数に、最後にアプリ オブジェクト コンストラクターにフローします。

プロジェクトのリソース

メイン プロジェクトのプロジェクト ファイル (.csproj) には、注目すべきセクションがいくつかあります。 初期 PropertyGroup では、プロジェクトがターゲットとするプラットフォーム フレームワークと、アプリケーション タイトル、ID、バージョン、表示バージョン、サポートされているオペレーティング システムなどの項目を指定します。 これらのプロパティは、必要に応じて変更できます。

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFrameworks>net6.0-android;net6.0-ios;net6.0-maccatalyst</TargetFrameworks>
        <TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net6.0-windows10.0.19041.0</TargetFrameworks>
        <!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
        <!-- <TargetFrameworks>$(TargetFrameworks);net6.0-tizen</TargetFrameworks> -->
        <OutputType>Exe</OutputType>
        <RootNamespace>MyMauiApp</RootNamespace>
        <UseMaui>true</UseMaui>
        <SingleProject>true</SingleProject>
        <ImplicitUsings>enable</ImplicitUsings>

        <!-- Display name -->
        <ApplicationTitle>MyMauiApp</ApplicationTitle>

        <!-- App Identifier -->
        <ApplicationId>com.companyname.mymauiapp</ApplicationId>
        <ApplicationIdGuid>272B9ECE-E038-4E53-8553-E3C9EA05A5B2</ApplicationIdGuid>

        <!-- Versions -->
        <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
        <ApplicationVersion>1</ApplicationVersion>

        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion>
        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
        <TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
    </PropertyGroup>
    ...

</Project>

最初のプロパティ グループの下にある ItemGroup セクションでは、最初のウィンドウが表示される前に、アプリの読み込み中に表示されるスプラッシュ画面の画像と色を指定できます。 また、アプリで使用されるフォント、イメージ、アセットの既定の場所を設定することもできます。

<Project Sdk="Microsoft.NET.Sdk">

    ...

   <ItemGroup>
        <!-- App Icon -->
        <MauiIcon Include="Resources\appicon.svg" 
                  ForegroundFile="Resources\appiconfg.svg" 
                  Color="#512BD4" />

        <!-- Splash Screen -->
        <MauiSplashScreen Include="Resources\appiconfg.svg" 
                          Color="#512BD4" 
                          BaseSize="128,128" />

        <!-- Images -->
        <MauiImage Include="Resources\Images\*" />
        <MauiImage Update="Resources\Images\dotnet_bot.svg" 
                   BaseSize="168,208" />

        <!-- Custom Fonts -->
        <MauiFont Include="Resources\Fonts\*" />

        <!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
        <MauiAsset Include="Resources\Raw\**" 
                   LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
    </ItemGroup>

    ...

</Project>

Visual Studio の [ソリューション エクスプローラー] ウィンドウで Resources フォルダーを展開して、これらの項目を表示できます。 アプリケーションに必要なその他のフォント、イメージ、その他のグラフィカル リソースをこのフォルダーとサブフォルダーに追加できます。

Visual Studio ソリューション エクスプローラーでメイン プロジェクトのリソース フォルダーが枠線で囲まれているスクリーンショット。フォルダーにはフォントと画像のファイルが含まれています。

アプリの実行を開始するときに、フォント フォルダーに追加されたすべてのフォントをアプリ ビルダー オブジェクトに登録する必要があります。 繰り返しになりますが、MauiProgram クラスの CreateMauiApp メソッドでは、ConfigureFonts メソッドを使用してフォントを登録しています。

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            ...
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            });

        ...
    }
}

この例では、AddFont メソッドではフォントを OpenSansRegular という名前に関連付けています。 このフォントは、ページの XAML の説明またはアプリケーション リソース ディクショナリで項目を書式設定するときに指定できます。

<Application ...">
    <Application.Resources>
        <ResourceDictionary>
            ...
            <Style TargetType="Button">
                ...
                <Setter Property="FontFamily" Value="OpenSansRegular" />
                ...
            </Style>

        </ResourceDictionary>
    </Application.Resources>
</Application>

Android と iOS のプラットフォーム固有のリソースには、Android 内の Resources フォルダー、および Platforms フォルダーの下にある iOS フォルダーを使用します。

知識チェック

1.

アプリによって表示される初期ウィンドウは、アプリケーション オブジェクトのどのメソッドで作成する必要がありますか?

2.

ボタンの Clicked イベントなど、コントロールのイベント ハンドラーのロジックはどこに実装しますか?