26
26
27
27
## これは何?
28
28
29
- * Epoxyは、.NET XAML環境で使える、Model-View-ViewModel (MVVM) アーキテクチャ向けの、独立した柔軟性のあるライブラリです。
30
- * C#を含む.NETの全処理系向け、及びF#用のNuGetパッケージがあります。
29
+ あなたは、XAMLを使用するGUIアプリケーションを作ったことはありますか? WPFから始まり、現在では、Avalonia, OpenSilver, MAUIなど、様々なXAMLプラットフォームが存在します。
30
+
31
+ これらのXAMLプラットフォームでは、特にMVVM (Model-View-ViewModel) アーキテクチャを併用することが推奨されているのですが、MVVMには解釈の違いによる方言も多く、また完全に統一された強固なアーキテクチャでもないため、実装しようとすると困難に直面することがあります。
32
+
33
+ Epoxyは、MVVMをアーキテクチャではなく、一種の道具として捉え、学習曲線を緩やかにして、MVVMビギナーへの理解の助けや導入の容易さ、簡単でありながら独立性が高く再利用のしやすい機能群となるように設計しました。
34
+
35
+ もちろん、Epoxyは初心者専用のライブラリというわけではありません。シンプルであるということは、様々な環境でも柔軟で応用性があるということです。(非公開ではありますが、Epoxyは複数の業務利用実績があります。)
36
+
37
+ 以下に、Epoxyの特徴を示します:
38
+
39
+ * C#を含む.NETの全処理系向け、及びF#用のNuGetパッケージがあります。
31
40
* 以下の環境をサポートしています:
32
41
* WPF: .NET 8.0/7.0/6.0/5.0, .NET Core 3.0/3.1, .NET Framework 4.5/4.8
33
42
* Avalonia: [ Avalonia] ( https://avaloniaui.net/ ) (New v11 or 0.10 series)
41
50
* 大げさにならない、最小の手間とコストで Model-View-ViewModel 設計を実現します。
42
51
* Viewにコードビハインドを書かずに済むことが着地点ですが、そのために煩雑な処理を記述しなければならなくなる事を避ける方針です。
43
52
* MVVMビギナーが躓きそうな部分に焦点を当てています。
44
- * 完全な共通化は行いません。Epoxyについてだけ同じように記述可能にし、その他の部分はそれぞれの環境に依存させることで、最大公約数的にならないようにしています 。
53
+ * 完全な共通化は行いません。Epoxyについてだけ同じように記述可能にし、その他の部分はそれぞれの環境に依存させることで、機能が最大公約数的にならないようにしています 。
45
54
* それぞれの機能が、相互に関係「しません」。独立しているので、自由に組み合わせることが出来ます。
46
55
* ほかのフレームワークライブラリ(例: ReactiveProperty)と組み合わせて使えるように、余計な操作や暗黙の前提を排除しています。
47
56
57
+ ## 導入方法
58
+
59
+ ターゲットとなるGUIフレームワークに対応したNuGetパッケージを導入してください。
60
+ Epoxyパッケージは沢山公開されていますが、必要なのは、あなたが使っているXAMLプラットフォームに対応する、以下の特定のパッケージのみです:
61
+
62
+ * ` Epoxy.Avalonia11 `
63
+ * ` Epoxy.Avalonia `
64
+ * ` Epoxy.WPF `
65
+ * ` Epoxy.OpenSilver `
66
+ * ` Epoxy.MAUI `
67
+ * ` FSharp.Epoxy.Avalonia11 `
68
+ * ` FSharp.Epoxy.Avalonia `
69
+ * ` FSharp.Epoxy.WPF `
70
+
71
+ 他に ` Epoxy.Core.WPF ` や` Epoxy.Build ` と言ったパッケージが見つかるかもしれませんが、
72
+ これらは上記のパッケージから依存して自動的に使用されます。
73
+
74
+ 注意: ` Epoxy.Templates ` には、テンプレートプロジェクト定義が含まれていましたが、1.15.0から廃止されました。これに伴い、Visual Studioのテンプレートウィザードも廃止されています。大丈夫です、ウィザードに頼らなくても、Epoxyは簡単に使い始めることができます!
75
+
76
+ フルスクラッチでEpoxyを導入したい、あるいは既存のプロジェクトにEpoxyを導入したい場合は、
77
+ [ ステップバイステップでコミットを作成した、Avalonia 11のサンプルリポジトリ] ( https://github.com/kekyo/Epoxy.Avalonia11.SampleProject ) が役に立つかもしれません。
78
+
79
+
80
+ ----
81
+
48
82
## サンプルコード
49
83
50
84
様々な環境の実働サンプルがあります。
59
93
サンプルコードプロジェクトは、[ playgroundディレクトリ] ( playground/ ) 、又はF#のサンプルコードは [ playground.FSharpディレクトリ] ( playground.FSharp/ )
60
94
にあります。
61
95
62
- フルスクラッチでEpoxyを導入したい、あるいは既存のプロジェクトにEpoxyを導入したい場合は、
63
- [ ステップバイステップでコミットを作成した、Avalonia 11のサンプルリポジトリ] ( https://github.com/kekyo/Epoxy.Avalonia11.SampleProject ) が役に立つかもしれません。
64
-
65
96
### 解説動画があります (YouTube, 日本語のみ):
66
97
67
98
[ ![ Epoxyで C# MVVMアーキテクチャを簡単に実装する話 - 作ってみた 第一回] ( https://img.youtube.com/vi/LkyrgJbuiQs/0.jpg )] ( https://www.youtube.com/watch?v=LkyrgJbuiQs )
68
99
69
100
[ (再生出来ない場合はこちら)] ( https://www.youtube.com/watch?v=LkyrgJbuiQs )
70
101
71
- ### 導入方法
72
-
73
- ターゲットとなるGUIフレームワークに対応したNuGetパッケージを導入してください。
74
- Epoxyパッケージは沢山公開されていますが、必要なのは:
75
-
76
- * ` Epoxy.Avalonia11 `
77
- * ` Epoxy.Avalonia `
78
- * ` Epoxy.WPF `
79
- * ` Epoxy.OpenSilver `
80
- * ` Epoxy.MAUI `
81
-
82
- などのパッケージのみです。
83
- 他に ` Epoxy.Core.WPF ` や` Epoxy.Build ` と言ったパッケージが見つかるかもしれませんが、
84
- これらは上記のパッケージから依存して自動的に使用されます。
85
-
86
- 注意: ` Epoxy.Templates ` には、テンプレートプロジェクト定義が含まれていましたが、1.15.0から廃止されました。
87
- これに伴い、Visual Studioのテンプレートウィザードも廃止されています。
88
102
89
103
----
90
104
91
105
## MVVMアプリケーションの実装を、最小限の手間で始める
92
106
93
- Model-View-ViewModelの役割についてのおさらい:
107
+ いますぐEpoxyの具体的な機能を確認したい場合は、 [ 機能一覧] ( #機能一覧 ) を参照してください。
108
+ ここでは、Model-View-ViewModelのそれぞれの役割について、おさらいします:
94
109
95
110
* ` View ` : XAMLでユーザーインターフェイスを記述し、` ViewModel ` とバインディングする(コードビハインドを書かない)。
96
111
* ` ViewModel ` : ` Model ` から情報を取得して、` View ` にマッピングするプロパティを定義する。
@@ -102,13 +117,17 @@ Model-View-ViewModelの役割についてのおさらい:
102
117
103
118
注意: MVVMの役割については諸説あります。
104
119
はじめから完全な設計を目指さずに、ブラッシュアップすると良いでしょう。
105
- Epoxyは段階的に改善する事を想定して開発しています 。
120
+ Epoxyは段階的に改善する事を想定して設計しています 。
106
121
107
- XAMLビューの定義とその実装を、MVVMに従って完全に分離しつつ、最小限の手間で実装する例です
122
+ XAMLビューの定義とその実装を、MVVMに従って完全に分離しつつ、最小限の手間で実装する例を示します。前節の、The CAT APIを使用する例です。
108
123
(このコードはWPFの例で、ポイントとなる点に絞っているため、完全な例はサンプルコードを参照して下さい):
109
124
110
125
### View (WPF XAML)の実装例
111
126
127
+ MVVMのViewとは、表示の見た目や構造をXAMLで定義します。ここには、動的な制御処理は記述しません。各コントロールの配置、色、フォントなどが含まれます。
128
+
129
+ ` ListBox ` コントロールは、複数の同じ見た目を持つ項目群を並べて表示する機能があります。
130
+
112
131
``` xml
113
132
<Window
114
133
x : Class =" EpoxyHello.Wpf.Views.MainWindow"
@@ -147,10 +166,27 @@ XAMLビューの定義とその実装を、MVVMに従って完全に分離しつ
147
166
148
167
### ViewModel (WPF)の実装例
149
168
150
- 完全に分離された、ViewModelクラスの実装です。
151
- 完全に、とは、つまりViewクラスに、コードビハインドを一切記述しないことを指します。
169
+ ViewModelの役割は、XAMLで定義された各コントロールを制御するコードを記述して、動的な振る舞いを持たせることです。
170
+
171
+ かつてのWindows Formsのように、なぜViewとViewModelの実装を一体化させないのか?という疑問には、さまざまな理由がありますが、現実的な問題として、 ` ListBox ` のような複数の要素に対して異なる内容を表示したり制御するのに、コードだけで実現するのは困難だからです。
172
+
173
+ これを解決するために、データバインディングと呼ばれる機能があり、データバインディングで問題を解決するために、MVVMというアーキテクチャが考案されたと言っていいでしょう。
174
+
175
+ ` ListBox ` の例で言うなら、ViewModelに定義されている ` Items ` コレクションの内容が、1対1で表示の各要素に対応するように、自動的に表示が更新されます。したがって:
176
+
177
+ * View側は各要素をどのように表示するか。配置や色やフォント、画像やその加工などをXAMLで指定する。
178
+ * ViewModel側は、各要素を追加、削除、あるいは順序の入れ替え、テキスト文字列や画像データの生成を行う。
179
+
180
+ ことに集中することができます。
181
+
182
+ ![ MVVM diagram] ( Images/mvvm.png )
183
+
184
+ 以下は、表示と制御が完全に分離された、ViewModelクラスの実装です。
185
+ 完全に分離、とは、つまりViewクラスに、コードビハインドを一切記述しないことを指します。
152
186
153
187
``` csharp
188
+ using Epoxy ;
189
+
154
190
// ステップ 1: ViewModelクラスを作ります。そしてViewModel属性を付与します。
155
191
// この属性は、PropertyChangedを自動的に実装して、XAML側に伝搬できるようにします。
156
192
[ViewModel ]
@@ -226,12 +262,12 @@ Modelの実装は、直接ユーザーインターフェイスを操作する事
226
262
非同期操作でタスクコンテキストを分離 ` task.ConfigureAwait(false) ` することで、
227
263
パフォーマンスを向上させることが出来ます。
228
264
265
+
229
266
----
230
267
231
268
## 機能一覧
232
269
233
- それぞれの機能は独立しているため、自由に組み合わせて使用出来ます
234
- (例えば、` ViewModel ` を継承していないと使えない、と言うような事はありません)。
270
+ 以下に、Epoxyの機能の一覧を示します。Epoxyのそれぞれの機能は独立しているため、自由に組み合わせて使用出来ます(例えば、ViewModelにありがちな、基底クラスの継承は必須ではありません)。
235
271
236
272
| 機能名| 概要|
237
273
| :----| :----|
@@ -328,7 +364,7 @@ csprojの`PropertyGroup`の`EpoxyBuildEnable`に`False`を指定して下さい
328
364
329
365
``` csharp
330
366
// Windowからのイベントを受信するWellを定義する
331
- public Well MainWindowWell { get ; } = Well .Factory .Create <Window >();
367
+ public Well < Window > MainWindowWell { get ; } = Well .Factory .Create <Window >();
332
368
333
369
// ...
334
370
@@ -406,11 +442,7 @@ Avaloniaでは、 `RoutedEvent` からイベントの引数 `EventArgs` の型
406
442
407
443
``` csharp
408
444
// Loadedイベントを受信するためのCommandプロパティの定義
409
- public Command ? Ready
410
- {
411
- get => this .GetValue ();
412
- private set => this .SetValue (value );
413
- }
445
+ public Command Ready { get ; private set ; }
414
446
415
447
// ...
416
448
@@ -476,7 +508,7 @@ MVVMアーキテクチャのレアケースにおいて、コントロールを
476
508
``` csharp
477
509
// PileをViewModelに配置します。
478
510
// (操作したいTextBoxのXAMLにAnchorを配置して、バインディングします)
479
- this . LogPile = Pile .Factory .Create <TextBox >();
511
+ public Pile < TextBox > LogPile { get ; } = Pile .Factory .Create <TextBox >();
480
512
481
513
// ...
482
514
@@ -490,6 +522,8 @@ await this.LogPile.RentAsync(async textBox =>
490
522
});
491
523
```
492
524
525
+ 注意: ` Anchor ` /` Pile ` でXAMLコントロールへのインスタンスをレンタルすると、コントロールに対してどのような操作も可能です。しかし、レンタル中にイベントをフックしたりすると、ViewModelの参照が保持されてしまい、メモリリークの原因となります。このようなフック操作は、出来るだけ` Fountain ` /` Well ` や` EventBinder ` を使用して下さい。
526
+
493
527
* [ For example (In WPF XAML)] ( https://github.com/kekyo/Epoxy/blob/main/playground/EpoxyHello.Wpf/Views/MainWindow.xaml#L39 )
494
528
* [ For example (In WPF view model)] ( https://github.com/kekyo/Epoxy/blob/main/playground/EpoxyHello.Wpf/ViewModels/MainWindowViewModel.cs#L74 )
495
529
@@ -832,6 +866,7 @@ Apache-v2
832
866
* Xamarin Formsを廃止。
833
867
* テンプレートプロジェクトを廃止。
834
868
* まだしばらくは新規プロジェクト生成として機能すると思いますが、更新されません。
869
+ * [ ステップバイステップでコミットを作成した、Avalonia 11のサンプルリポジトリ] ( https://github.com/kekyo/Epoxy.Avalonia11.SampleProject ) が役に立つかもしれません。
835
870
* 互換性の為に残されていたObsoleteメンバーを削除。
836
871
* 1.14.0:
837
872
* Avalonia 11で、XAMLからEpoxyを参照する際の名前空間にURLを指定可能にしました。
0 commit comments