LoginSignup
7
8

More than 1 year has passed since last update.

.NET MAUI+Blazor を始めてみた

Last updated at Posted at 2023-02-04

はじめに

Windows のデスクトップアプリを作るのに自分は、以前は Delphi を使っていて、仕事は WinForms+VB.NET を使っていて、趣味は Electron も使っています。新たにアプリを作り始めるのに、別の開発手段も試してみようと思いました。

.NET MAUI とは

.NET Multi-Platform App UI (. NET MAUI) は、C# と XAML を使用して、ネイティブのモバイル アプリやデスクトップ アプリを作成するための、クロスプラットフォーム フレームワークです。
.NET MAUI とは - .NET MAUI | Microsoft Learn

チュートリアルのソースコードの一部を見てみます。

MainPage.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="●●.MainPage">

    <ScrollView>
        <VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="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
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";
    }
}

XAML で画面の定義して C# でロジックを実装します。いわゆるウェブアプリが HTML で画面の定義して JavaScript でロジックの実装するのと似ています。

.NET MAUI を始めてみた

Visual Studio を使う

参考:Visual Studio 2022 をインストールする - .NET MAUI | Microsoft Learn

プロジェクトを新規作成する

参考:初めての .NET MAUI アプリをビルドする - .NET MAUI | Microsoft Learn

新規プロジェクトの内容を確認する

アプリのベースになるプロジェクトは簡単に作成できましたが、ファイルが幾つもあります。どのファイルを変更すればいいのか。それを知るために、プロジェクトに含まれるファイルを調べてみました。

MauiProgram.cs

エントリポイントは、MauiProgram.cs のようです。

MauiProgram.cs
public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>();

        return builder.Build();
    }
}

builder.UseMauiApp<App>(); で指定されている App の定義を探します。

App.xaml および App.xaml.cs

App.xaml.csApp というクラスの定義がありました。

App.xaml.cs
public partial class App : Application
{
    public App()
    {
        InitializeComponent();

        MainPage = new AppShell();
    }
}
App.xaml
<?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:●●"
             x:Class="●●.App">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
                <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

App.xaml.cs で new されている AppShell の定義を探します。

AppShell.xaml および AppShell.xaml.cs

AppShell.xamlAppShell.xaml.cs がありました。

AppShell.xaml.cs
public partial class AppShell : Shell
{
    public AppShell()
    {
        InitializeComponent();
    }
}
AppShell.xaml
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="●●.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:●●"
    Shell.FlyoutBehavior="Disabled">

    <ShellContent
        Title="Home"
        ContentTemplate="{DataTemplate local:MainPage}"
        Route="MainPage" />

</Shell>

ContentTemplate="{DataTemplate local:MainPage}" および Route="MainPage" で指定されている MainPage の定義を探します。

MainPage.xaml および MainPage.xaml.cs

MainPage.xamlMainPage.xaml.cs がありました。ようやく画面を定義しているファイルに辿り着きました。

MainPage.xaml.cs
public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }
}
MainPage.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="●●.MainPage">

    <ScrollView>
        <VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center">
        
        (中略)

        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

このファイルを修正すればいいようです。

このファイルを MauiProgram.cs で指定すればいいように思いましたが、AppShell クラスでルーティング機能つまりページ遷移を実装しています。

.NET MAUI を始めてみたが

●●.xaml.cs●●.xaml とセットになっています。WinForms+C# のアプリで ●●.cs●●.Designer.cs がセットになるのと同じでしょうか。
WinForms アプリを Visual Studio で開発するときはビジュアルデザイナが使えるので ●●.Designer.cs は直接編集することがありませんが、.NET MAUI アプリは Visual Studio でも ●●.xaml を直接編集しないといけないようです。

MainPage.xaml に手を加え始めましたが、思ったように書けそうにありません。自分は以前に WPF アプリを作ろうとして、このときも XAML の編集に馴染めなくて挫折していました。

.NET MAUI の記事を読み漁っていると、Blazor で開発するという記事を見つけました。

.NET Blazor とは

Blazor は、開発者が C# と HTML を使用してウェブアプリを作成できるようにする、無料のオープンソースのフレームワークです。これは Microsoft によって開発されています。
Blazor - Wikipedia

チュートリアルのソースコードの一部を見てみます。

Counter.razor
@page "/counter"

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

前半は HTML そのもので、後半は C# のコードです。XAML より書きやすそうです。

.NET Blazor を始めてみた

Visual Studio を使う

参考:Blazor チュートリアル | ダウンロードしてインストールする

プロジェクトを新規作成する

参考:Blazor チュートリアル | 最初の Blazor アプリをビルドする

Blazor サーバアプリと Blazor クライアントアプリ

Blazor アプリは、

  • サーバで実行されて HTML がレンダリングされるタイプ「Blazor Server アプリ」
  • クライアントのブラウザ上で実行されるタイプ「Blazor WebAssembly アプリ」

参考:ASP.NET Core Blazor | Microsoft Learn

サーバサイド Blazor を始めてみた

まず、サーバサイド Blazor アプリを作ってみました。

プロジェクトの内容を確認する

アプリのベースになるプロジェクトは簡単にできましたが、ファイルが幾つもあります。どのファイルを変更すればいいのか。それを知るために、プロジェクトに含まれるファイルを調べてみました。

Program.cs

エントリポイントは、Program.cs のようです。

Program.cs
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();

var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();

app.MapFallbackToPage("/_Host"); で指定されている _Host の定義を探します。

Pages/_Host.cshtml

Pagesフォルダに _Host.cshtml がありました。

_Host.cshtml
@page "/"
@using Microsoft.AspNetCore.Components.Web
@namespace ●●.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <base href="~/" />
    <link href="css/site.css" rel="stylesheet" />
    <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
    <component type="typeof(App)" render-mode="ServerPrerendered" />

    <script src="_framework/blazor.server.js"></script>
</body>
</html>

<component type="typeof(App)" で指定されている App の定義を探します。

App.razor

App.razor がありました。

App.razor
<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <p>Sorry, there's nothing at this address.</p>
    </NotFound>
</Router>

<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" で指定されている MainLayout の定義を探します。

MainLayout.razor

MainLayout.razor がありました。

MainLayout.razor
@inherits LayoutComponentBase

<main>
    @Body
</main>

@Body に何か埋込されるようです。

参考:ASP.NET Core Blazor レイアウト | Microsoft Learn
参考:ASP.NET Core の Blazor ルーティングとナビゲーション | Microsoft Learn

起動時には "/" が指定されたページが埋込されます。

Pages/Index.razor

Pagesフォルダに Index.razor がありました。

Index.razor
@page "/"

<h1>Hello, world!</h1>

このファイルを修正すればいいようです。ようやく画面を定義しているファイルに辿り着きました。

このファイルを _Host.cshtml で指定すればいいように思いましたが、App.razorRouter コンポーネントを使ってルーティング機能つまりページ遷移を実装しています。

クライアントサイド Blazor を始めてみた

続いて、クライアントサイド Blazor アプリを作ってみました。

新規プロジェクトの内容を確認する

アプリのベースになるプロジェクトは簡単に作成できましたが、ファイルが幾つもあります。どのファイルを変更すればいいのか。それを知るために、プロジェクトに含まれるファイルを調べてみました。

Program.cs

エントリポイントは、Program.cs のようです。サーバサイドのアプリと違っています。

Program.cs
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

await builder.Build().RunAsync();

builder.RootComponents.Add<App>("#app"); で指定されている #appApp の定義を探します。

wwwroot/index.html

wwwrootフォルダの index.html<div id="app"> がありました。

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <base href="/" />
    <link href="css/app.css" rel="stylesheet" />
</head>
<body>
    <div id="app">Loading...</div>

    <script src="_framework/blazor.webassembly.js"></script>
</body>

</html>

<div id="app"> にコンテンツが埋込されるようです。

App.razor

App.razor がありました。ここからサーバサイド Blazor アプリと同じです。

.NET MAUI+Blazor を始めてみた

プロジェクトを新規作成する

参考:BlazorWebView を使用して .NET MAUI アプリで Blazor Web アプリをホストする - .NET MAUI | Microsoft Learn

新規プロジェクトの内容を確認する

アプリのベースになるプロジェクトは簡単に作成できましたが、ファイルが幾つもあります。これのどこを変更すればいいのか。それを知るために、プロジェクトに含まれるファイルを調べてみました。

MauiProgram.cs

エントリポイントは、MauiProgram.cs のようです。XAML を使った MAUI アプリと同じです。

MauiProgram.cs
public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>();

        builder.Services.AddMauiBlazorWebView();
        builder.Services.AddSingleton<WeatherForecastService>();

        return builder.Build();
    }
}

builder.Services.AddMauiBlazorWebView();builder.Services.AddSingleton<WeatherForecastService>(); が加わっています。

builder.UseMauiApp<App>(); で指定されている App の定義を探します。

App.xaml および App.xaml.cs

App.xaml.cs
public partial class App : Application
{
    public App()
    {
        InitializeComponent();

        MainPage = new MainPage();
    }
}
App.xaml
<?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:●●"
             x:Class="●●.App">
    <Application.Resources>
        <ResourceDictionary>
            (中略)
        </ResourceDictionary>
    </Application.Resources>
</Application>

App.xaml.cs で new されている MainPage の定義を探します。

MainPage.xaml および MainPage.xaml.cs

MainPage.xaml.cs
public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }
}
MainPage.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"
             xmlns:local="clr-namespace:●●"
             x:Class="●●.MainPage"
             BackgroundColor="{DynamicResource PageBackgroundColor}">

    <BlazorWebView HostPage="wwwroot/index.html">
        <BlazorWebView.RootComponents>
            <RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
        </BlazorWebView.RootComponents>
    </BlazorWebView>

</ContentPage>

XAML を使った MAUI アプリは、このファイルで画面の定義していましたが、Blazor を使った MAUI アプリは、 <BlazorWebView> が配置されていて、wwwroot/index.html が埋込されているようです。
<RootComponent Selector="#app" ComponentType="{x:Type local:Main}" /> で指定されている #appMain の定義を探します。

wwwroot/index.html

wwwrootフォルダに index.html ファイルがあります。クライアントサイド Blazor アプリと同じです。

Main.razor

Blazor アプリの App.razor と同じです。ここから Blazor アプリと同じです。App.razor でないのは App.xaml があるからでしょうか。

.NET MAUI+Blazor を始めてみたが

.NET MAUI+Blazor アプリは、実行ファイルを作るのは MAUI のフレームワークだが、アプリの機能を実装するのは基本的に Blazor になります。
エントリポイントから Blazor を実行するまでは、変更することはないでしょう。アプリの機能を実装するには、MainLayout.razor あるいは Pages/Index.razor 辺りを編集します。
Blazor は、HTML+CSS+JavaScript の代わりに HTML+CSS+C# で書くので、XAML+C# を新たに覚えて使うより楽かも知れません。

7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8