MVVM + Prism

GUI作りたいよね、windows デスクトップアプリかっこいいよね、というよりは、MVVMフレームワークを理解して、reactive property したいよね、というモチベーションである。

なので、メインはプログラムを完成させることよりも、フレームワークを理解することなので、大したものは作らず、深堀りする方向でまとめまとめしてみる。

O先生がたくさんやってるので、その手助けもできるかもしれないし、それ以前にやっている人が近くにいるならば、分からなかったらその人にいろいろ聞けるし、何より話ができるしいいこといっぱい?と思ってやってみる

最初の参考記事↓

【改訂版】PrismとReactivePropertyで簡単MVVM! - Qiita
本記事は、3年前に書いた以下の記事を大幅に見直して書き改めたものです。 PrismとReactivePropertyで簡単MVVM! 上記の記事は、私の古い認識のもとに書き上げられました。 私の当時の認識で、 Prismの機能のごく一部を使って WPFアプリケーションを構成することが「簡単」だと思っていましたが、時が過ぎ、その認識が変化しました。 即ち、 Prismの機能にもう少し乗っかった方が、結果的に「簡単」だと思い直したのです。 また、当時の未熟さから、誤った考えのもとに書かれた部分も見受けられます。 古い記事に「いいね」をいただく度、そのことをお伝えし直したいという気持ちになっていましたが、この度、執筆するやる気を確保できましたので、本記事を投稿するに至りました。 Prism の機能は多彩ですが、本記事では覚えておくと開発が簡単になる、効果の高い部分のみをピックアップしてお伝えできればなと思います。 今まで、 WPFは.NET Framework固有のものでした。 しかし、2019年秋にリリースされるであろう.NET Core 3.0には、新たに WPFの機能が乗せられており、.NET Frameworkと同じように WPF アプリケーションを作成できるようになります。 世間では、 Javascriptを中心に、新たなGUIフレームワークが台頭しつつありますが、まだ WPF の人口も残っているのではないでしょうか。 本記事の執筆時点では正式リリースがまだですが、以下では.NET Core 3.0-previewを使用し、簡単な WPFのサンプルアプリの作成を通して、 Prismと ReactiveProperty の使用方法をご紹介します。 Windows 10 Home dotnetcore-sdk 3.0.100-preview5-011568 Prism.Unity 7.2.0.1233-pre ReactiveProperty 5.5.1 Visual Studio Code Nugetを見ると、 Prism関連のパッケージがたくさんあります。 ここで、各パッケージの意味を見てみましょう。 Prism.Coreは前提パッケージで、プラットフォーム共通の機能が入っています。 Prism.Wpfと Prism.Formsは、それぞれ WPF用と Xamarin用です。 その下の6つのパッケージは WPF用で、DIコンテナとしてそれぞれの外部パッケージを使用するものです。 最後の3つは Xamarin 用で、DIコンテナとしてそれぞれの外部パッケージを使用します。 WPFアプリを作るうえでは、 WPF用でコンテナありの6つの中から選択することになります。 今回は、.NET Core対応ありで公式サンプルにも使用されている、 Prism.Unity を使用します。 Prism.Unityは Prism.Wpfに依存し、 Prism.Wpfは Prism.Coreに依存するので、 Prism.Unity だけインストールすれば大丈夫です。 UnityはDI(依存性の注入)ライブラリです。 Unityという同名のゲームエンジンが存在しますが、全く関係はありません。 DIライブラリは沢山ありますが、 C#においてはこの Unity が有名どころです。 Prism.Unityは Unityに依存するので、 Prism.Unity だけインストールするようにしましょう。 Prism.Unity を使用した、公式サンプルです。 Prism-Samples-Wpf ...
https://qiita.com/hiki_neet_p/items/e04b5ac692aa18df0968

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

はじめての WPF【step: 1 .NET Core WPF 入門 2020】 | :: halation ghost ::
当サイトの WPF 入門記事としては既に WPF Prism episode シリーズ がありますが、 WPF Prism episode シリーズ を書いていた頃は右も左も分からず、試したことをとりあえず記事にしていたような状況だったので 1 つのネタで記事を書いた後に別の情報が見つかる事や、新しい方法を思い付く事も多く、本来 1 エントリに書くべき情報が複数の記事に分散する状況になった連載だと反省しています。 ですが現状では管理人もある程度 WPF や MVVM に慣れ、機能や流れも整理できてきたので新たに 2020 年版の WPF 入門として連載を開始する事にしました。 尚、この記事は Visual Studio 2019 Community Edition で .NET Core 3.1 以上 と C# を使用して、WPF アプリケーションを作成するのが目的のエントリなので、C# の文法や基本的なコーディング知識を持っている人を対象にしています。 WPF は Windows Presentation F oundation の略称で、.NET Framework 3.0(2006/11/6 リリース)以降に含まれる Windows クライアントアプリの実行プラットフォームです。 発表当時はそれなりに騒がれていた記憶はありますが、あっと言う間に名前を聞かなくなり、技術的な情報もあまり増えないまま現在に至っている気がします。その後も Microsoft は UWP を発表しますが WPF 以上に鳴かず飛ばずの状態に思えるので、UWP は既に風前の灯火だと感じています。 .NET における Windows クライアントアプリの開発プラットフォームは Windows Form から始まり WPF → UWP と発表されて来ましたが結局、現時点でも最も使用されているのはおそらく Windows Form だろうと思われる皮肉な状況です。 日本国内では業務系システム開発に従事する人数はおそらく系統別では最多人数を誇ると思っていますが、技術力は低く技術に興味が薄い人が大半を占めると管理人は感じているので、今まで慣れている Windows Form を捨てて右も左も分からない WPF に移行するリスクを冒す選択はしないだろうと思っています。(あくまでも管理人個人の考えです)しかも WPF を選択したとしても得られるのが『コントロールの外観を自由に変更できてかっこいい感じの画面が作れるよ!』だけでは当然の結果のような気はします。 WPF(UWP 含む)が普及しない最大の原因はその学習コストの高さにある と管理人は考えていて、WPF を覚えようとして調べると『XAML』、『データバインディング』、『MVVM』、『Prism』、『Livet』、『ReactiveProperty』、『DI』、『ユニットテスト』...
https://elf-mission.net/programming/wpf/getting-started-2020/step01/

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

ReactiveProperty を編む【step: 7 .NET Core WPF MVVM ReactiveProperty 入門 2020】 | :: halation ghost ::
前回記事「Prism に Model ⇔ VM の双方向バインドは難しい【step: 6 .NET Core WPF Prism MVVM 入門 2020】」 前回は Prism だけで Model ⇔ VM 間を疑似的に双方向バインドする方法等を紹介しましたが、結果的に Prism だけで実現するのは難しい事も分かりました。そのため、今回は Prism の MVVM サポートクラス等は使用せず ReactiveProperty を使用してデータを Model ⇔ VM ⇔ View 間をそれぞれ双方向でバインドする方法を紹介します。 尚、この記事は Visual Studio 2019 Community Edition で .NET Core 3.1 以上 と C# + Prism
https://elf-mission.net/programming/wpf/getting-started-2020/step07/

electron typescript react material - UIでGUI

electron typescript vue でGUI

Electron + Vue.js + TypeScriptでWindowsアプリ開発環境を構築する手順(2020年版) - Code for final
アプリを開発したくなり、前から気になってたElectronで作ってみようと調べてたらVue.jsが使えることがわかり、 アプリの開発環境を構築ようとしたものの、思いのほかつまづいたので対処方法をメモっときます。 たぶん時が流れると状況は変わってくると思うので2020年現在の手順と理解ください。 web(HTML+ CSS)の技術でデスクトップアプリを作成できる フレームワークです。 ちなみにVisual Studo CodeはElectronでできています。 現時点で推奨版となっている12.18をダウンロードしてインストールします。 インストールは次へ次へでOKです。 すでに入っているひとはスキップでOKです。 Vue CLIはVue.jsで開発するのにほぼ必須なツールです。 Visual Studio Code を起動してターミナルを開いて以下のコマンドを実行する。 >npm install -g @vue/cli vue uiはプロジェクトの作成や プラグインのインストール、ビルドなどを GUIで行えるようになる便利なツールです。 Vue CLIに同梱されていますので別途インストールは不要です。 Vue CLI インストールが終わったら以下のコマンドをたたいてvue uiを起動します。 >vue ui ここで以下のエラーがでました。 PS C:\Users\final> vue ui vue : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Users\final\AppData\Roaming\npm\vue.ps1 を読み込むことができま せん。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。 発生場所 行:1 文字:1 +
https://final.hateblo.jp/entry/2020/06/03/141040
Electron, TypeScript, React, Material-UI で簡単なメモ帳アプリを作る - Qiita
Electron、TypeScript、React、Material-UI の学習メモです。 Wikipediaの記事が端的で分かりやすかったので転載。 Electronは、GitHubが開発したオープンソースのソフトウェアフレームワークである。 Chromiumと Node.js を使っており、HTML、CSS、JavaScriptのようなWeb技術で、macOS、Windows、Linuxに対応したデスクトップアプリケーションをつくることができる。 https://ja.wikipedia.org/wiki/Electron_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2) SPAなどと大体同じ要領で、スタンドアロンでも動作するデスクトップアプリを作れるようになります。 Chromeの開発者ツールも利用できます。 マイクロソフトによって開発されたプログラミング言語です。 JavaScriptを 静的型付け の仕様でラッピングしたようなもので、コンパイル後のソースはバイナリファイルではなく、JavaScriptのテキストファイルです。 TypeScript Facebookによって開発された、JavaScriptのライブラリです。 HTMLと、それを操作するJSのロジックをセットにした「コンポーネント」を組み合わせることで、WEBページを構築します。 Googleが提唱するマテリアルデザインに準拠したUIパーツを、Reactのコンポーネントとして提供しているライブラリです。 自分でCSSを用意せずとも、素敵なWEBページをすぐに構築できます。 Node.js、npmが既に導入済みであることを前提に進めます。 プロジェクトのルートフォルダで、下記コマンドを実行して初期設定ファイルを出力します。 コンパイル後のJSのバージョンは2017にしました。 こちらの記事を参考にいたしました。ありがとうございます。 VSCodeでESLint+@typescript-eslint+Prettierを導入する(v2.0.0修正版) 初期設定ではダブルクォート指定の為、シングルクォートも可に上書きしました。 こちらの記事を参考にいたしました。ありがとうございます。 TypeScriptとElectron WebpackでTypeScriptを扱う為のLoaderもインストールします。 TypeScriptのコンパイル設定を strictに設定している為、nodeのモジュールを requireでインポートする際に、暗黙のanyに対してエラーが発生します。 今回は、コメントでエラーをスキップしてみました。 targetは、webpackに環境を伝えるプロパティです。 Targets | webpack mainには、エントリーポイントとなるコンパイル後のファイルを指定します。 開発時はwebpackはウォッチモードで。 TypeScript用の定義ファイルも一緒に取得します。 Material-UIのアイコンも取得しています。 ReactコードのコンパイルはTS側で行うため、Webpackのloaderや設定は不要です。 .eslintrc.jsonに設定を追記します。 Propsの型チェックはTypeScriptで行うので、 react/prop-typesは off にします。 拡張機能の ESLintを追加します。 setting.json にて、入力時にチェックし、保存時にフォーマット修正をするようにします。 まだまだ理解がふんわりしているのですが、とりあえず環境構築できました。 疲れた。息切れ。 create-react-app を利用すると、もっと手順が減ります。 プロジェクトフォルダ内に、下記のファイルとフォルダを準備します。 後で使うMaterial-UIで利用するフォントのリンクもついでに入れておきます。 React×TypeScriptのサンプルコードで、関数コンポーネントのインターフェースとして React.SFCを利用しているものを見かけますが、廃止予定のようですね。 React 16.7 - React.SFC is now deprecated | stackoverflow webPreferences: { nodeIntegration: true }は、セキュリティ上好ましくない設定だそうですが、一旦これで進めます。 リモートコンテンツで、Node.js integration を有効にしない | electron 【Electron】nodeIntegration: ...
https://qiita.com/koedamon/items/e2f858511863dcc4852e

WPF is 何

Windows Presentation Foundation

What is WPF? - Visual Studio
Windows Presentation Foundation (WPF) is a UI framework that creates desktop client applications. The WPF development platform supports a broad set of application development features, including an application model, resources, controls, graphics, layout, data binding, documents, and security.
https://docs.microsoft.com/en-us/visualstudio/designers/getting-started-with-wpf?view=vs-2019

きーわーど

Target Frameworkについて

WPFアプリをvisual studio で作成する場合、Target Frameworkとしていろいろ選べる。

大まかに分けて、

がある。

【2020年版】.NET Framework / .Net Core / Xamarinの関係を整理~そして.NET 5へ - LIGHT11
NET関連の フレームワークは概念も歴史も複雑でよくわからなくなりがちです。 .NET 5という大きい転換点が訪れるこのタイミングで、現時点で.NETの理解に必要な知識をざっとまとめてみました。 .NETをめぐる物語は2000年に マイクロソフトが Microsoft .NETという戦略を発表するところから始まります。 そしてその後に、この構想が実装されたものとして、.NET Frameworkが誕生します。 .NET Frameworkを使うと Windows アプリケーションやWebアプリケーションを作ることができます。 さてこの.NET Frameworkの特徴として、いろんな言語で記述が行えるということがあります。 例えば今、同じ処理を C#で書いた ソースコードと Visual Basic .NETで書いた ソースコード があることを考えます。 .NET Frameworkでは、これらを一度 共通中間言語(Common Intermediate Language / CIL)と呼ばれるものに変換します。 このCILは、 C#から コンパイルしても VB.NETから コンパイルしても同じものが出来上がります。 つまりこの時点で言語間の差異が吸収されます。 ただしCILはまだ機械が読める状態ではないのでここからさらにネイティブコードへの変換をかける必要があります。 このときに使われるのが 共通言語ランタイム(Common Language Runtime / CLR)と呼ばれる 仮想マシンです。 これがCILを読んで処理を行うことにより最終的に ソースコード が実行されます。 前節の.NET Frameworkは
https://light11.hatenadiary.com/entry/2020/05/24/200141

やはり混沌としているようで、ざっくりまとめると、

  1. 2000年にマイクソフトが打ち出したMicrosoft .NETという戦略・構想の実装として、.NET Frameworkが誕生した。このフレームワークを使用することによってMicrosoft Windowsで動作可能な様々なアプリケーションを作成することができた。
  1. 他のプラットフォームでも動作可能なアプリケーションを作成するために、新しいフレームワークである .NET Coreを発表。MITライセンス。でも .NET Frameworkで準拠していた .NETの仕様を満たしている。
  1. .NET Coreと同じように、マルチプラットフォームなフレームワークとしてXamarin社のMonoというフレームワークも存在していた。
  1. この時点で3つ存在していることになる。(カオス)
  1. そのため、これら3つのフレームワークを統一して1つのフレームワークとしてみた結果が .NET 5である。

今(2021年3月現在)はとりあえずおとなしく .NET5を使用する。

XAML ざむる

eXtensible Application Markup Language

Microsoftが開発したXMLの仕様に準拠したGUI記述用のマークアップ言語。

マークアップ言語とは、文章を構造化するための言語です。「文章を構造化する」というと、なんだか非常に難しそうな印象を受けますが、基本的には「ここはタイトル部分です」「ここから本文が始まります」「ここは非常に重要な部分です」など、人間であれば直感的に理解できる事柄を、タグや記号で表示し、コンピューターに認識させることを指します。
マークアップ言語とは - Markup Languageの種類とその歴史 | マイナビクリエイター
マークアップ言語とは、文章を構造化するための言語です。「文章を構造化する」というと、なんだか非常に難しそうな印象を受けますが、基本的には「ここはタイトル部分です」「ここから本文が始まります」「ここは非常に重要な部分です」など、人間であれば直感的に理解できる事柄を、タグや記号で表示し、コンピューターに認識させることを指します。 ...
https://mynavi-creator.jp/blog/article/what-is-mark-up-language

これで何をするのかというと、GUIの中身を構成するために使用する。

XAMLが登場する前は、どのように記述していたかというと、C# やVBAなどの言語を使用していた。

昔適当に作ったやつを除いてみると、

WindowsFormsApp

NameCreatedTags
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を用意した理由。

コンテンツモデル

大切な考え方らしい。

WPF4.5入門 その47 「コンテンツモデル」 - かずきのBlog@hatena
WPFの重要なコントロールの1つにContentControlクラスがあります。このクラスは、Contentプロパティに設定された単一の要素を表示するという機能を提供するコントロールです。「WPFのコンセプト」でも紹介しましたが、このコントロールが、要素を表示する際の詳細なロジックを以下に示します。 ...
https://blog.okazuki.jp/entry/2014/08/25/164331

かずきさんのブログによれば、

WPFの重要なコントロールの1つにContentControlクラスがあります。このクラスは、Contentプロパティに設定された単一の要素を表示するという機能を提供するコントロールです。
Windows FormsからWPFへ乗り換えるときの最初の障壁 - かずきのBlog@hatena
Twitterでも呟いたのですが、とりあえずブログのエントリとしてまとめておきます。因みに、ここでの障壁はプログラマさんが感じるであろう最初の障壁を自分の場合を思い出して書いています。 何がなんだかわからない まず、最初に躓くのが慣れ親しんだWindows ...
https://blog.okazuki.jp/entry/20110224/1298560658

こっちのがわかりやすく書いている。

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>

で登場する

というタグ、クラス(それぞれ、System.Windows.Controlsに所属)でどのようなプロパティを持っているかを見てみると、

Window Class (System.Windows)
Provides the ability to create, configure, show, and manage the lifetime of windows and dialog boxes.
https://docs.microsoft.com/en-us/dotnet/api/system.windows.window?f1url=%3FappId%3DDev16IDEF1%26l%3DEN-US%26k%3Dk(System.Windows.Window);k(VS.XamlEditor)%26rd%3Dtrue&view=net-5.0

Grid Class (System.Windows.Controls)
Defines a flexible grid area that consists of columns and rows. public ref class Grid : System::Windows::Controls::Panel, System::Windows::Markup::IAddChild public class Grid : System.Windows.Controls.Panel, System.Windows.Markup.IAddChild type Grid = class inherit Panel interface IAddChild Public Class Grid Inherits Panel Implements IAddChild Inheritance Implements The following example demonstrates how to create a grid.
https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.grid?f1url=%3FappId%3DDev16IDEF1%26l%3DEN-US%26k%3Dk(System.Windows.Controls.Grid);k(VS.XamlEditor)%26rd%3Dtrue&view=net-5.0

ContentControl Class (System.Windows.Controls)
Represents a control with a single piece of content of any type. public ref class ContentControl : System::Windows::Controls::Control, System::Windows::Markup::IAddChild [System.Windows.Localizability(System.Windows.LocalizationCategory.None, Readability=System.Windows.Readability.Unreadable)] [System.Windows.Markup.ContentProperty("Content")] public class ContentControl : System.Windows.Controls.Control, System.Windows.Markup.IAddChild [ ] [ ] type ContentControl = class inherit Control interface IAddChild Public Class ContentControl Inherits Control Implements IAddChild Inheritance Derived Attributes Implements The following example demonstrates how to create the four buttons shown in the Remarks section.
https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.contentcontrol?f1url=%3FappId%3DDev16IDEF1%26l%3DEN-US%26k%3Dk(System.Windows.Controls.ContentControl);k(VS.XamlEditor)%26rd%3Dtrue&view=net-5.0

Button Class (System.Windows.Controls)
Represents a Windows button control, which reacts to the Click event. public ref class Button : System::Windows::Controls::Primitives::ButtonBase public class Button : System.Windows.Controls.Primitives.ButtonBase type Button = class inherit ButtonBase Public Class Button Inherits ButtonBase Inheritance The following example shows three buttons that respond to clicks in three different ways.
https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.button?f1url=%3FappId%3DDev16IDEF1%26l%3DEN-US%26k%3Dk(System.Windows.Controls.Button);k(VS.XamlEditor)%26rd%3Dtrue&view=net-5.0

という感じで、Grid Class 以外はcontent プロパティを含まないことが分かった。

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

しらんわこんなん。