前の記事以降で .NET6 MAUI preview4 をいじってみて知ったことあれこれ

## ReactiveProperty動くらしい

かずきさんの[**このページ**](https://zenn.dev/okazuki/articles/helloworld-on-maui-preview4)を参考に
……普通に動く

### 結論

いつもお世話になっています！とても助かってますね


## Androidはpreview4でも実機が使える

`adb devices`で認識していれば`dotnet build -t:Run -f net6.0-android`で大丈夫

### 結論

デバッグが捗りますね


## Windows版のデバッグをするには (Package)

`dotnet new maui -o HelloWorld`でプロジェクトを作ったとしたら。
Windows版のデバッグは`HelloWorld.WinUI3 (Package)`をスタートアッププロジェクトにする

### 結論

WinUIのデバッグをしたことがないのが丸わかりですね


## dotnet new maui の -o と -n

`dotnet new maui`コマンドのオプション、`-o`と`-n`では結果が違う。

`dotnet new maui -o HelloWorld`だと以下のようなファイルの配置になるが、

```text
  HelloWorld
    HelloWorld
      Android
      HelloWorld.csproj
      MacCatalyst
      iOS
    HelloWorld.WinUI3
    HelloWorld.WinUI3 (Package)
    Directory.Build.targets
```

`dotnet new maui -n HelloWorld`だと以下のようになる

```text
  HelloWorld
    HelloWorld
      HelloWorld
        Android
        HelloWorld.csproj
        MacCatalyst
        iOS
    HelloWorld.WinUI3
    HelloWorld.WinUI3 (Package)
    Directory.Build.targets
```

### 結論

`dotnet new maui`コマンドで`-n`は使ってはいけないですね


## NavigatePage をちゃんと使うには

`Startup.cs`に`.UseMauiControlsHandlers()`を加える

```csharp
using Microsoft.Maui.Controls.Hosting;
```

これ入れて

```csharp
			appBuilder
				.UseFormsCompatibility()
				.UseMauiControlsHandlers()
				.UseMauiApp<App>()
```

こうする
こうしないと全く白紙だったりして悩むことになる（5時間くらい）

### 結論

テンプレートも直して欲しいですね


## Prismがprerelease出している

[Prism.Maui](https://github.com/dansiegel/Prism.Maui)

```shell
$ dotnet new maui -o HelloWorld
$ cd HelloWorld/HelloWorld.WinUI3
$ dotnet add package Prism.Maui --prerelease
$ dotnet add package Prism.DryIoc.Maui --prerelease
$ cd ../HelloWorld
$ dotnet add package Prism.Maui --prerelease
$ dotnet add package Prism.DryIoc.Maui --prerelease
```

として、`Startup.cs`は上記も参考にして、以下に変更

```csharp
			appBuilder
				.UseFormsCompatibility()
				.UseMauiControlsHandlers()
				.UsePrismApplication<App>(x => x.UseDryIoc())
```

`App.xaml`は以下で

```xml
<prism:PrismApplication
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:HelloWorld"
    xmlns:prism="http://prismlibrary.com"
    x:Class="HelloWorld.App">

</prism:PrismApplication>
```

`App.xaml.cs`は以下のように

```csharp
	public partial class App : PrismApplication
	{
		public App() : this(null)
		{
		}

		public App(IContainerExtension container) : base(container)
        {
			InitializeComponent();
		}

		protected override async Task OnWindowCreated(IActivationState activationState)
        {
			Microsoft.Maui.Controls.Compatibility.Forms.Init(activationState);

			this.On<Microsoft.Maui.Controls.PlatformConfiguration.Windows>()
				.SetImageDirectory("Assets");

			await NavigationService.NavigateAsync("/NavigationPage/MainPage");
		}

		protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
			containerRegistry.RegisterForNavigation<NavigationPage>();
			containerRegistry.RegisterForNavigation<MainPage>();
        }
	}
```

`using`は適宜追加で。
ただ、View-ViewModelを

```csharp
			containerRegistry.RegisterForNavigation<MainPage, MainPageViewModel>();
```

とするとまだエラーになるようで。（2021/06/02現在の、8.1.27-alphaにて）
View + `ViewModel` というクラス名にして、Viewだけ指定しておけばViewModelを使ってくれます。
（もちろんXAML側にViewModelLocatorとか指定は要りますが）

### 結論

着々と環境が整っていってますね


## ViewsとかViewModelsとかディレクトリ掘った時

WinUIのプロジェクトはソースファイルを相対パスで読み込んでいる
ディレクトリを掘ったりすると、読んでくれなくて悩むことになる（1時間くらい）

.csprojファイルを直接編集する

```xml
	<ItemGroup>
		<Compile Include="..\HelloWorld\*.cs" Link="%(FileName)%(Extension)" />
	</ItemGroup>

	<ItemGroup>
		<EmbeddedResource Remove="Windows\*.xaml" />
		<EmbeddedResource Include="..\HelloWorld\*.xaml" Link="%(FileName)%(Extension)" />
	</ItemGroup>
```

こうなってるようなところを

```xml
	<ItemGroup>
		<Compile Include="..\HelloWorld\*.cs" Link="%(FileName)%(Extension)" />
		<Compile Include="..\HelloWorld\Views\*.cs" Link="Views\%(FileName)%(Extension)" />
		<Compile Include="..\HelloWorld\ViewModels\*.cs" Link="ViewModels\%(FileName)%(Extension)" />
	</ItemGroup>

	<ItemGroup>
		<EmbeddedResource Remove="Windows\*.xaml" />
		<EmbeddedResource Include="..\HelloWorld\*.xaml" Link="%(FileName)%(Extension)" />
		<EmbeddedResource Include="..\HelloWorld\Views\*.xaml" Link="Views\%(FileName)%(Extension)" />
		<EmbeddedResource Include="..\HelloWorld\ViewModels\*.xaml" Link="ViewModels\%(FileName)%(Extension)" />
	</ItemGroup>
```

こう直す

```xml
		<Compile Include="..\HelloWorld\**\*.cs" Link="%(RecursiveDir)%(FileName)%(Extension)" />
```

こうすると、AndroidやiOSのファイルまで読んでしまうのでダメ

### 結論

仕組み上仕方ないのですが、将来に期待ですね