MVVM + Prism
GUI作りたいよね、windows デスクトップアプリかっこいいよね、というよりは、MVVMフレームワークを理解して、reactive property したいよね、というモチベーションである。
なので、メインはプログラムを完成させることよりも、フレームワークを理解することなので、大したものは作らず、深堀りする方向でまとめまとめしてみる。
O先生がたくさんやってるので、その手助けもできるかもしれないし、それ以前にやっている人が近くにいるならば、分からなかったらその人にいろいろ聞けるし、何より話ができるしいいこといっぱい?と思ってやってみる
最初の参考記事↓

この通り動作するように環境を構築したりすることはできたけれども、そもそもwpfってなんぞという理解ができてなかったので、もう少し調べてみることにしてみた。


これがある程度できたら、JavaScriptでGUI作ってみよう。
↓


electron typescript react material - UIでGUI
electron typescript vue でGUI


WPF is 何
Windows Presentation Foundation

きーわーど
- XAML
- データバインディング
- MVVM
- Prism
- Livet
- ReactiveProperty
- DI
- ユニットテスト
Target Frameworkについて
WPFアプリをvisual studio で作成する場合、Target Frameworkとしていろいろ選べる。
大まかに分けて、
- .NET Framework
- .NET Core
- .NET5
がある。

やはり混沌としているようで、ざっくりまとめると、
- 2000年にマイクソフトが打ち出したMicrosoft .NETという戦略・構想の実装として、.NET Frameworkが誕生した。このフレームワークを使用することによってMicrosoft Windowsで動作可能な様々なアプリケーションを作成することができた。
- 他のプラットフォームでも動作可能なアプリケーションを作成するために、新しいフレームワークである .NET Coreを発表。MITライセンス。でも .NET Frameworkで準拠していた .NETの仕様を満たしている。
- .NET Coreと同じように、マルチプラットフォームなフレームワークとしてXamarin社のMonoというフレームワークも存在していた。
- この時点で3つ存在していることになる。(カオス)
- そのため、これら3つのフレームワークを統一して1つのフレームワークとしてみた結果が .NET 5である。
今(2021年3月現在)はとりあえずおとなしく .NET5を使用する。
XAML ざむる
eXtensible Application Markup Language
Microsoftが開発したXMLの仕様に準拠したGUI記述用のマークアップ言語。
マークアップ言語とは、文章を構造化するための言語です。「文章を構造化する」というと、なんだか非常に難しそうな印象を受けますが、基本的には「ここはタイトル部分です」「ここから本文が始まります」「ここは非常に重要な部分です」など、人間であれば直感的に理解できる事柄を、タグや記号で表示し、コンピューターに認識させることを指します。

これで何をするのかというと、GUIの中身を構成するために使用する。
XAMLが登場する前は、どのように記述していたかというと、C# やVBAなどの言語を使用していた。
昔適当に作ったやつを除いてみると、
WindowsFormsApp
Name | Created | Tags |
---|---|---|
Properties | ||
References | ||
App.Config | ||
Form1.cs | ||
main.cs | ||
hogehoge.cs |
という感じの構成になっていた。
これはwindows form appの場合でmain.csでInitializeComponent()メソッドの中でめちゃくちゃたくさんクラスを作成してテキストボックスとかボタンとかを指定している。
C#の言語仕様に則ってGUIのボタン配置などを指定していた。
正直構造わかりにくいし、もっと簡単に書きたい。
統一的かつ簡素なGUIの記述方法は何だろうかと考えると、HTMLのようなマークアップ言語でそれぞれのGUI上の機能を記述する方法である。
なんでHTMLにしなかったのか分からないけれども、結果、MicrosoftはXMLの仕様に則った、XAMLというものを生み出したのだと思う。
実際のXAMLの例
↓
<Window x:Class="PrismSample.Lib.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/"
xmlns:local="clr-namespace:PrismSample.Lib.Views"
mc:Ignorable="d"
prism:ViewModelLocator.AutoWireViewModel="True"
Title="MainWindow" Width="800" Height="450" FontSize="40"
Loaded="OnLoaded">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ContentControl Grid.Column="0" Margin="20"
prism:RegionManager.RegionName="OperandRegion"/>
<ContentControl Grid.Column="1" Margin="20"
prism:RegionManager.RegionName="AnswerRegion"/>
<Button>
<Button.FontWeight>Bold</Button.FontWeight>
<Button.Content>
<WrapPanel>
<TextBlock Foreground="Blue">Multi</TextBlock>
<TextBlock Foreground="Red">Color</TextBlock>
<TextBlock>Button</TextBlock>
</WrapPanel>
</Button.Content>
</Button>
</Grid>
</Window>
xmlnsはXAML NameSpaceであり、XAMLを機能させるために必要な機能などを格納しているライブラリ、名前空間を参照している。
名前空間を参照しておくことによってその名前空間内に存在するクラスを利用することが可能になる。
- 参照する名前空間を指定しないとその先のクラスを使用することができない。
- サイズやコントロールなどもここですべて記述することもできるし、分割して記述することも可能である。(上の例は分割版)
という感じで、C#やVBAなどでGUIの実装を書くのではなくて、実装の記述はXAMLというマークアップ言語に切り分けて書いてあげよう、というのがXAMLを用意した理由。
コンテンツモデル
大切な考え方らしい。

かずきさんのブログによれば、
WPFの重要なコントロールの1つにContentControlクラスがあります。このクラスは、Contentプロパティに設定された単一の要素を表示するという機能を提供するコントロールです。
こっちのがわかりやすく書いている。
WPFは、コンテンツモデルという初見の人にとってはよくわからないものが採用されています。何か表示するものを1つだけ持つものはContentというプロパティで、それを指定します。このContentはobject型なのでなんでも入ったりするという、Windows Formsから見たら考えられない状態になっていますが、とりあえず文字列を入れれば大丈夫です。
つまいどういうことかというと、XAMLで書かれているタグはそれぞれクラス、を表しており、そのクラスのプロパティの中にContentが含まれているか否かで、表示できる個数が制限されている、と解釈することができる。
例えば以下のコード
<Window x:Class="PrismSample.Lib.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/"
xmlns:local="clr-namespace:PrismSample.Lib.Views"
mc:Ignorable="d"
prism:ViewModelLocator.AutoWireViewModel="True"
Title="MainWindow" Width="800" Height="450" FontSize="40"
Loaded="OnLoaded">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ContentControl Grid.Column="0" Margin="20"
prism:RegionManager.RegionName="OperandRegion"/>
<ContentControl Grid.Column="1" Margin="20"
prism:RegionManager.RegionName="AnswerRegion"/>
<Button Content="Button"
Grid.Column="1"
HorizontalAlignment="Left"
Margin="0,39,0,0"
VerticalAlignment="Top"/>
</Grid>
</Window>
で登場する
- Window
- Grid
- ContentControl
- Button
というタグ、クラス(それぞれ、System.Windows.Controlsに所属)でどのようなプロパティを持っているかを見てみると、
- Window Class ある


- Grid Class ない


- ContentControl Class ある


- Button Class ある


という感じで、Grid Class 以外はcontent プロパティを含まないことが分かった。
何でもはいるプロパティだけど、入れれる個数は1つだけ、という存在なのでwindow クラスのcontentにはGrid クラスを入れてあげて、gridクラスはcontentクラスを持たないからそのコンテンツは制限なしに放り込むことができるため、ContentControl やButton、はてまた登場しなかったけどImageやTextBoxなどもいっしょくたにできるのである。
しらんわこんなん。