.NET 6 Preview 4 で MAUI が使えるみたいなので試してみた

4 min read読了の目安(約4300字

Build 2021 にあわせて MAUI のプレビューが出てきました。

https://devblogs.microsoft.com/dotnet/announcing-net-maui-preview-4/

インストールは maui-check というツールがあるので、それをインストールして実行すると足りないものを検出してインストールをやるか確認してくれます。
maui-check を完了すると (私の場合は OS 再起動が必要でした) Visual Studio 2021 16.11.0 Previewプロジェクトテンプレートに .NET MAUI App が出てきます。

プロジェクトを作ると以下のような感じのプロジェクトが作られました。

Android, iOS, macOS はシングルプロジェクトですが Windows に関しては現時点だと Windows UI Library 3.0 用のプロジェクトが追加で 2 つ作られるようです。

以下のような感じで MAUI のプロジェクト 1 つで Android, iOS, macOS 切替が出来そうです。

このままビルドすると、いくつかの NuGet パッケージが無いというエラーになりました。試していたのが深夜だったので、ツイートをしてから寝て起きたら Drastic Actions(@drasticactionSA) さんが以下のようなメンションをくれてました。ありがとうございます!

https://twitter.com/drasticactionSA/status/1397243759973355529?s=20

該当 GitHub を見ると NuGet のパッケージのソースとして https://aka.ms/maui-preview/index.json を追加していたので NuGet.config ファイルをソリューションに作成して以下の内容で作成しました。

NuGet.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
	<packageSources>
		<add key="maui-preview" value="https://aka.ms/maui-preview/index.json" />
	</packageSources>
</configuration>

この状態で Android エミュレーターに対してデバッグ実行を行うと以下のようなダイアログが出ました orz

ですが、ビルドログを見てみるとデプロイは成功していたのでエミュレーターのアプリ一覧を見ているとありました!

起動してみると動きました。

WinUI3 (Package) というサフィックスのプロジェクトをスタートアッププロジェクトに指定すると、WinUI 版のものが起動しました。

iOS の方はローカル環境の macOS の Xcode の更新をさぼってたせいで Xcode が古くて起動できませんでした。現在 Xcode 更新中です…。

ReactiveProperty 入れてみた

MauiApp1 と MauiApp1.WinUI3 プロジェクトに ReactiveProperty を NuGet から追加します。そして以下のような ReactiveProperty を試すときのお約束の ViewModel を作ります。

MainPageViewModel.cs
using Reactive.Bindings;
using Reactive.Bindings.Extensions;
using System;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;

namespace MauiApp1
{
    public class MainPageViewModel : IDisposable
    {
        private readonly CompositeDisposable _disposables = new CompositeDisposable();
        private ReactivePropertySlim<string> _input;
        public ReactivePropertySlim<string> Input => _input ??= 
            new ReactivePropertySlim<string>("").AddTo(_disposables);

        private ReadOnlyReactivePropertySlim<string> _output;
        public ReadOnlyReactivePropertySlim<string> Output => _output ??=
            _input.Delay(TimeSpan.FromSeconds(3))
                .Select(x => x?.ToUpper())
                .ObserveOnUIDispatcher()
                .ToReadOnlyReactivePropertySlim()
                .AddTo(_disposables);

        private ReactiveCommand _resetCommand;
        public ReactiveCommand ResetCommand => _resetCommand ??=
            _input.Select(x => !string.IsNullOrEmpty(x))
                .ToReactiveCommand()
                .WithSubscribe(() => Input.Value = "")
                .AddTo(_disposables);

        public void Dispose() => _disposables.Dispose();
    }
}

MainPage.xaml は ViewModel を BindingContext に設定して以下のように変更します。

MainPage.xaml
<ContentPage
    x:Class="MauiApp1.MainPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:MauiApp1"
    BackgroundColor="{DynamicResource PageBackgroundColor}">
    <ContentPage.BindingContext>
        <local:MainPageViewModel />
    </ContentPage.BindingContext>
    <StackLayout>
        <Entry Text="{Binding Input.Value}" />
        <Label Text="{Binding Output.Value}" />
        <Button Command="{Binding ResetCommand}" Text="Reset" />
    </StackLayout>
</ContentPage>

MainPage.xaml.cs に元々入ってたカウントアップのコードがあるので、それは消してコンストラクタだけにしておきます。実行してみましょう。

ばっちりですね。WinUI3 の方で実行してみたら動かなかったので、今後の MAUI の実装に期待しておきます。

まとめ

とりあえず出たら試してみたくなるので、試してみました。後でちゃんとドキュメントを読みます。