.NET MAUIとMVUフレームワークCometについて

# はじめに
.NET MAUIにはCometというMVUフレームワークが存在します。
今回はこのCometをちょこちょこ触ってどんな感じなのかを共有出来たらなと思います。

# インストール方法
これが最新のちゃんとしたインストール方法なのかわかりませんが、とりあえずGitHubの公式ドキュメントに従ってインストール作業をしてみます。

https://github.com/dotnet/Comet

インストールガイドはこちら、ここの1番、テンプレートのインストールのみでOKです。

https://github.com/dotnet/Comet/wiki/Getting-Started#to-make-your-ride-more-enjoyable

VScode用みたいに書いていますがVisualStudioでも一応できました。
VScodeでサンプルアプリを立ち上げたい場合は最後まで手順に沿ってコマンドを売ってもらえばOKです。

# Visual Studioでテンプレートアプリを開く
テンプレートがインストールされたのでVisualStudioの新規作成からCometTemplateを選べるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/885e1be5-df67-9b29-644c-6b5bd2b0fefd.png)
検索窓にCometと入力すると出てきます。

追加の情報ダイアログが出てきますがスルーしてOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/546914da-8891-9783-955a-f4bcfbf826b8.png)

テンプレートができたのでとりあえずWindowsでデバックしてみると、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/8b57209a-7402-7bc6-33df-f2e6fdab516e.png)
？なんだこれ？めっちゃ小さくなってね？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/1736428d-ca99-5993-d0e1-4c7d9cc319bc.png)
あ、ちゃんとできてた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/43212845-3974-633f-5f70-afc0fa3055ef.png)
と思ったらウィンドウの枠広げたり位置移動させたりするとわけのわからない挙動になります。
マジか、、、

Windowsにも対応って書いていますが今のところiOSやAndroidなんかのウィンドウサイズが変わらないモバイルアプリ用なのでしょうか、、、

# 気を取り直してCodeを書いてみる。
サンプルコードの中身はこちら

```cs
namespace CometSample;
public class MainPage : View
{

	[State]
	readonly CometRide comet = new();

	[Body]
	View body()
		=> new VStack {
				new Text(()=> $"({comet.Rides}) rides taken:{comet.CometTrain}")
					.Frame(width:300)
					.LineBreakMode(LineBreakMode.CharacterWrap),

				new Button("Ride the Comet! ☄️", ()=>{
					comet.Rides++;
				})
					.Frame(height:44)
					.Margin(8)
					.Color(Colors.White)
					.Background(Colors.Green)
				.RoundedBorder(color:Colors.Blue)
				.Shadow(Colors.Grey,4,2,2),
		};

	public class CometRide : BindingObject
	{
		public int Rides
		{
			get => GetProperty<int>();
			set => SetProperty(value);
		}

		public string CometTrain
		{
			get
			{
				return "☄️".Repeat(Rides);
			}
		}
	}
}
```
まぁちょっとした機能しかないけどC#で全部書こうとするとこのくらいのコード量にはなるのかなぁ？

早速普段のMAUIのサンプルアプリみたいにイメージを追加しようとして問題が起こりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/df2689cf-c5eb-9f7c-3c1d-7ee917ae4d97.png)
あれ？できないのかぁ

じゃあこれは？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/06bef411-a61d-bd4e-dce8-ecd85eb3e361.png)
？プロパティまたはインデクサーは読み取り専用で割り当てることができない？
なんじゃそれ

少し調べてみましたが、要素のプロパティには関数かプロパティを作ってしか割り当てることができないらしい。
これがMVUか、、、

こんな感じにしてやっとイメージを貼り付けることができました。
```cs
public class MainPage : View
{

	[State]
	readonly CometRide comet = new();
	[State]
	readonly string imageSource = "dotnet_bot.png";//←Stateを作りそこに定数だったりの値を入れる必要がある。

	[Body]
	View body()
		=> new VStack {
			new Image(imageSource),//←StateのimageSourceを割り当てる
```
Imageの因数にすでにImageSourceが割り当てられているようですね、、、

この辺のコントロールの形も若干おかしい
LabelもTextになってて()ないでTextプロパティを指定するようになってた。
```cs
new Text(()=> $"({comet.Rides}) rides taken:{comet.CometTrain}")
    .Frame(width:300)
	.LineBreakMode(LineBreakMode.CharacterWrap),
```

そしてボタンを押すたびイメージが横移動するように作ったのがこちら
```cs
public class MainPage : View
{
	[State]
	readonly CometRide comet = new();
	[State]
	readonly string imageSource = "dotnet_bot.png";

	[Body]
	View body()
		=> new VStack {
	     		new Image(imageSource)
                    .TranslationX(comet.Rides),//←comet.Ridesを使いまわしてみた関数やプロパティであれば引数として持ってくることは可能らしい
				new Text(()=> $"({comet.Rides}) rides taken:{comet.CometTrain}")
					.Frame(width:300)
					.LineBreakMode(LineBreakMode.CharacterWrap),

				new Button("Ride the Comet! ☄️", ()=>{
					comet.Rides++;
				})
					.Frame(height:44)
					.Margin(8)
					.Color(Colors.White)
					.Background(Colors.Green)
				.RoundedBorder(color:Colors.Blue)
				.Shadow(Colors.Grey,4,2,2),
		};

	public class CometRide : BindingObject
	{
		public int Rides
		{
			get => GetProperty<int>();
			set => SetProperty(value);
		}

		public string CometTrain
		{
			get
			{
				return "☄️".Repeat(Rides);
			}
		}
	}
}
```

# さいごに
MVCのフレームワークに初めてチャレンジしてみましたが、なかなかこの概念を理解するのは難しそうだと思いました。

安全なんだとは思いますが、決まりきった定数にもStateつけて、、、ってのをすべてにやらないといけないとなるとかなりしんどいなと、、、
自分がFlutter入門動画を見たときなんでこんなことしてんだ？って違和感はこれだったのかもしんねぇ、、、

とりあえずMAUIにはMVVMがあるのでMVUはお預けにしようかと思います。(Windowsだと挙動もおかしいしね)