今更エッセンシャルWPFを読んでみる

# 動機とか雑感とか
- WPF+C#(特にXAML)が使いこなせていないので「エッセンシャルWPF」を買ってみて読んでみる。
- 結構翻訳が微妙…というか無理…内容を理解して翻訳していないだろう…読み終わったら速攻でメル○リかも。
- 写経もいいのだが分量が多いのでしんどいので、[あるリポジトリ](https://github.com/rimever/EssentialWpf)においてあったコードを勉強に使わせてもらった。ありがとうございます！
- この本を1冊目に読むのはキツい。C#を知らない人は無論無理。WPFを全く使ったことがない人にはほとんど参考にならない。
    - WPFのWPFの本は本当に少ないがKindle Unlimitedに初心者向けのものもあるからチェックしてほしい。
    - WPFの開発苦労話みたいなものも含まれている。興味がない人からするとノイズかもしれない。

# 1章 はじめに
- Windows FormsとWPFはUIの作り方が違うだけで根本的には同じなのかと思ったが、全然違うらしい。
    - Windows Formsはラスタベース、WPFはベクタベースらしい。つまりWPFは拡大しても図などがザラザラしない。
    - ほかにも表示系がいろいろ違うらしい。例えばボタンに画像と文字を一緒に表示するのも得意らしい(MFCでもできた気がするが…)
- XAMLをボタンの描画なども含めてIEできれいに表示できるみたいな記述があって「うそだあ」と思ってやってみたができなかった。
- XAMLのタグとC#の型には対応関係がある。どちらを使っても同じものが書けるようである(C#というよりCLRで走る言語かな)。
    - XAMLでタグを追加するということは、C#でオブジェクトを作るのと等しい。逆もまた然りということか。
    - XAML特有の謎なプロパティの書き方`x:Name`はC#における属性`[STAThread]`とかとほぼ同様に機能するらしい。いわれてみればそんな気がしないでもない。ちなみにこのプロパティの書き方は**マークアップ拡張**と呼ばれる。
- `xmlns:x`とか`xmlns:d`は使用する名前空間の指定をしている。ここでいえば`x`や`d`は名前空間名であり、XAML内の識別子として使用できる。だから`x`ではなく`xaml`だってよい。この名前空間の指定方法は2つあるようだ。
    - URLっぽく記述する(例: `xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml/presentation"`)
    - 読み込むアセンブリ(DLL)とアセンブリ内の名前空間を記述する(例: `xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"`)
- ウィンドウは1つのクラスであらわされるが、そのクラスは2つに分割される。1つ目はXAMLで記述し、コンパイルでC#に変換されるもの。もう1つは最初からC#で書くやつ(コードビハインドとも呼ばれる)。これらは`Partial Class`という仕組みで関係を持たせながらも独立して開発できるようになっている。
- Windows Formsと違うポイントとしてXAMLで使用するコントロールには必ずしも名前を付けなくてよい。名前を付ける場合は`x:Name`属性を使用する。
- あらゆるコントロールには`Resource`という属性があり、そこにはKey-Valueの形で属性値を書いておける。この属性値はそのコントロールに内包される子コントロールから参照することができる。
- 最後にコントロールの`Template`プロパティという非常に重要な機能についての言及があるが、何を言っているのかよくわからん。
    - どう考えても[こちらのページ](https://ufcpp.net/study/dotnet/wpf_template.html)の説明がわかりやすい。
    - **コントロールの形状などをむちゃくちゃカスタマイズしたい場合**に`Template`というプロパティに形状情報などを記述するとよいということだ。

# 2章 アプリケーション
- `xmlns`と`xmlns:x`は何が違うのか。これらはプロジェクト作成時に自動生成されるが、それぞれ微妙に違うURLが設定されて何がしたいのかよくわからん
    - [こちらの神ページ](https://blog.okazuki.jp/entry/20130103/1357188241)に説明が書いてある。
    - `xmlns`は極めて基本的なベースとなるXAMLの機能を使えるようにするおまじない
    - `xmlns:x`は名前空間`x`に割り当てる機能を指定する。`x`はデータバインディングなどに使用するもので、`xmlns`で指定したものよりもより高度な機能をアドインするようなイメージだろうか。
- 1章でも登場したがXAMLはWebアプリケーションの開発にも使えるらしい。Webアプリケーションの形式でビルドすると`.xbap`という拡張子が与えられたファイルとなり、ブラウザ上で実行できる。
    - これは知らなかった。でもオワコンらしい。
- WPFではMDI(Multiple Document Interface)をサポートしない。MDIは昔はよく見た気がするが、最近は確かにあまり見ない。
    - そういえば、ウェブブラウザなんて1つのプロセスで複数のウェブサイトを閲覧できるが、これはMDIには含まれないのか。
- 例外に関して気になる記述があった。`回復が不可能な例外が存在するということです。典型的な例として、StackOverflowException、OutOfMemoryException、ThreadAbortExceptionがあります`
    - ふうん。どれも普段見かけない例外なのでよく知らんが、回復が不能な例外というのはCatchできないということか？
    - たしかに[StackOverflowExceptionのMicrosoft Docs](https://docs.microsoft.com/en-us/dotnet/api/system.stackoverflowexception?view=net-5.0#examples)には`Starting with the .NET Framework 2.0, you can't catch a StackOverflowException object with a try/catch block, and the corresponding process is terminated by default`という記述がある。
    - 一方で[ThreadAbortExceptionのMicrosoft Docs](https://docs.microsoft.com/en-us/dotnet/api/system.stackoverflowexception?view=net-5.0#examples)には`ThreadAbortException is a special exception that can be caught, but it will automatically be raised again at the end of the catch block`と書いてある。Catchはできるけど握りつぶすことはできないという感じか。
    - [OutOfMemoryExceptionのMicrosoft Docs](https://docs.microsoft.com/en-us/dotnet/api/system.outofmemoryexception?view=net-5.0)には特に記述はなさそうだった。試しにこの例外をわざとthrowしても普通にCatchできた。
    - この`回復が不可能`っていうのはどういう意味なのか結局よくわからなかった。これらの3つの例外に処理上の共通点があるというわけじゃなくて、単に発生した場合はもう実行継続しないほうがいいよってことだろうか。
- Windowsデスクトップアプリに限らず、ユーザの設定情報を保存しておきたいことは多いだろう
    - 本書では`ApplicationSettingsBase`というクラスを使用した設定の保存方法を紹介している。これは知らなかった。[この神サイト](https://dobon.net/vb/dotnet/programing/applicationsettingsbase.html)ではVisual Studioを使わない方法として紹介されている。なるほど。Visual StudioのGUI上で設定を作っていくのではなく、コード上でやりたい場合にとる手法なのか。
    - ただ、特別な理由がなければ[この神サイト](https://dobon.net/vb/dotnet/programing/mysettings.html)のVisual Studioを使う方法のほうがわかりやすいような気がする。
    - ほかにもXMLファイルやレジストリなどに出力する方法があるが、ファイルの管理を手動でゴリゴリやり始めると間違えて大事な設定を上書きしちゃったり、互換性が確保されなかったりといろいろ面倒なことも多い気がする。
- 子ウィンドウを親ウィンドウの上にフローティングさせながらも、親ウィンドウを選択可能な状態にするにはOwner属性を設定する。
    - 恥ずかしながら知らなかった。[このサイト](https://www.ipentec.com/document/csharp-wpf-set-window-owner)にあるような効果もあるらしい。親を閉じたら子も閉じるようにするためにわざわざ通知を送ったりしていた過去があるなんて人に言えない…
- WPFでは画面遷移(Navigation)の機能が備えられている。要はWebページみたいにハイパーリンクで他のページに移動したり、戻ったりするというようなものだ。
    - 登場人物は3名。`ナビゲーションホスト`、`ページ`、`ジャーナル`である。
    - ナビゲーションホストはブラウザのようなものでページを表示させる土台となるものである。
    - ページはブラウザに表示されるWebページのようなもので、実際のコンテンツの中身や他のページへのリンクが含まれる。
    - ジャーナルは遷移の履歴情報である。ブラウザで戻る/進むの操作をしたかったら、どういう経路で遷移しているのかを覚えておく必要がある。それがジャーナルである。履歴といったもWebページの閲覧履歴とは違って、何か一本の動線のようなイメージだ。

# 3章 コントロール
- WPFのコントロールの特徴はリッチなコントロールとシンプルなプログラミング性を両立したところといえるようだ。
    - `リッチ`とはボタンの中にさらにボタンを含むような自由度や、様々なフォントや文字色、図形を組み合わせたゴージャスな表現力のこと。
    - `シンプルなプログラミング`とはなるべく少ないコードで直感的にコントロールを表現できること。
- これを実現するのにWPFでは`コンテンツモデル`という仕組みを採用している。そのためのクラスが`ContentPresenter`である。
    - `ContentPresenter`はアダプターみたいなものだ。コントロールの上に`ContentPresenter`というなんでも固定できるアダプターを取り付けることでその上に文字を置くのもよし、画像を置くのもよし、複数の要素を置くのもよしというような感じに上に載るものを抽象化できる装置であると読めた。
    - `ContentPresenter`のことを本書では"馬車馬"と表現しているが、それだとめっちゃ酷使されそうだが誤訳か？荷馬車？
- `ContentPresenter`はボタンなどの中身が1つのものに使用し、リストなどの複数の項目を一覧表示するには`ItemsPresenter`を使用する。
    - ボタンの中に複数のコントロールを表示することは可能だが、あくまで表示する"キャンバス"は1つである。一方、ListBoxなどは"キャンバス"が明確に区切られている。よって`ItemsPresenter`を使用することになる。
    - `ListBox`は`ListBoxItem`という子要素の集まりである。`ListBoxItem`はボタンと同様にコントロールを表示する"キャンバス"は1つだけだから`ContentPresenter`を使用する。よって`ListBox`の下に`ItemsPresenter`があり、その中には複数の`ListBoxItem`が含まれていて、それぞれに`ContentPresenter`があるというような構造か。
- コントロールの種類は`コンテンツコントロール`、`レイアウトコントロール`、`レンダコントロール`の3つ。
    - コンテンツコントロールはボタンやリストなどのこと。
    - レイアウトコントロールは`StackPanel`などの他のコントロールを制御するもの。
    - レンダコントロールは画面上にピクセルを表示するものである。例えば画像とか矩形とか。
- ここまでは**コントロールの中に何を描くか**だったが、次は**コントロールの見た目**の話だ。当然、**何を書くか**は**見た目**の一部であるから、より上位の概念を考えることになる。
    - コントロールの見た目はコントロールのプロパティ`ControlTemplate`で設定する。`ControlTemplate`の中にボタンの外形や枠などの見た目の情報や、前述の`ContentPresenter`などを階層構造に記述していく。これを`VisualTree`と呼ぶことがある(?)ようだ。
    - `ControlTemplate`については[これ](https://noumenon-th.net/programming/2017/11/19/button/)や[これ](https://ufcpp.net/study/dotnet/wpf_template.html)などの文献のほうがわかりやすい。
    - 知らなかったがXAMLではなく、[コードでControlTemplateを記述する方法](https://araramistudio.jimdo.com/2016/12/07/wpf%E3%81%A7template%E3%82%92%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E4%BD%9C%E3%82%8B/)もあるようだ。まあわからんでもない内容だがXAMLのほうが階層がはっきりしていて好み。
    - `ControlTemplate`を使うと名前の通りテンプレ化することができる。つまりボタンの見た目を簡単に統一することができる。そういった点でいうと、[このページ](https://ufcpp.net/study/dotnet/wpf_template.html)に書いてあるようにリソースに`ControlTemplate`を書く方法が最高にクールだと思う。
- `ItemsControl`はリストのように複数の項目からなるリストである。[ここ](http://yujiro15.net/YKSoftware/StandardControls_ItemsControl.html)の最高に明快な解説のとおり、普通にリストのソースにコレクションを指定するだけでは全然使い物にならないリストである。様々な属性を設定しながらリストをリッチにしていく必要がある。
    - 上で紹介した記事と同じ作者だとおもうけど「[WPF実践](http://kisuke0303.sakura.ne.jp/blog/wordpress/wp-content/uploads/2016/08/4843696230c1698ad8ff7d086b998344.pdf)」の6章の説明がわかりやすい。
- なんちゃらTemplateが一体どこに効いてくるのか、どんな書き方をすればいいのかは難しい。上記の「WPF実践」もわかりやすいが、[こちらの記事](http://grabacr.net/archives/1240)もあわせて読んで実際に何かコントロールを作ってみるとわかりやすい。
    - `DataTemplate`と`ControlTemplate`のどちらを使うべきなのか迷うことが多い。[この記事](https://tocsworld.wordpress.com/2014/09/28/wpf%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC/)とか[この記事](https://tan.hatenadiary.jp/entry/20151022/1445440049)がわかりやすい。カスタマイズをしたいなら`ControlTemplate`、シンプルに行きたいなら`DataTemplate`という感じか。
- 訳者の人には悪いが全体的にヒドい訳だ。英単語をそのまま翻訳して、英語の語順を日本語のものに直しただけというような印象すら受ける。本当に内容を理解して訳したのか疑問だ。
- WPFにはほかにも様々なコントロールがある。`InkCanvas`なんてめちゃくちゃ面白そうだが、一生使うことはないんだろうなあ。

# 4章 レイアウト
- レイアウトとは3章で出てきたようなコントロールをどのように配置するかということである。
    - WPFのコントロールの特徴は`ContentPresenter`を使用してコントロールの中にコントロールを入れる**ネスト**ができることであった。レイアウトもそれと同様にレイアウトの中に他のレイアウトをネストすることができる。
    - レイアウトのネストができるようになると**親レイアウト**と**子レイアウト**というような親子関係が生まれる。ここで問題になるのがその親子間でのデータの受け渡しである。その受け渡しの技術を**コントラクト**というらしい。
- コントロールの位置調整の方法として`RenderTransform`と`LayoutTransform`の2つのプロパティがある。
    - `RenderTransform`はレイアウトの決定後に位置調整する。たとえばボタンを整列するようにレイアウトしていて、そのなかのボタンを`RenderTransform`で位置変更したら、他のボタンの位置を乱すことなくボタンの位置が変わる。
    - `LayoutTransform`はレイアウトの決定時に位置の調整分を加味する。
    - [このサイトの図](https://blog.scottlogic.com/2008/12/19/layouttransform-vs-rendertransform-whats-the-difference.html)を見てもらえばわかりやすい。Button Twoと書かれたボタンが位置調整されているが、レイアウトが決まってから回転しているのか、レイアウトを決めるときに回転が加味されているのかがわかりやすい。
    - どちらがよいのかという話だが、`RenderTransform`のほうがレイアウトの再計算が必要なく、ビデオカードで位置調整が可能だからパフォーマンスとしては優れているようだ。
- コントロールを並べてレイアウトを制御するための土台(いわば台紙)を**パネル**と呼び、`Canvas`、`StackPanel`、`DockPanel`などがある。
    - パネルを使用するうえで興味深いのが**添付プロパティ**である。`<Canvas...><Button Canvas.Top=".../></Canvas>`のように本来`Button`が知りえない(Buttonクラスのプロパティに含まれるはずのない)`Canvas.Top`というプロパティを、あたかも持っているかのように`Button`がふるまっている。これはいまだにどういう仕組みなのかよく理解できていないが、[ここの説明](http://yujiro15.net/YKSoftware/tips_AttachedProperty.html)が簡潔で分かりやすい。
    - `Canvas`はいわば`ウィンドウという掲示板に張り付けられた紙`である。この紙の中に表示されるコントロールは紙の左上の位置からの相対位置で配置することができる。よって紙の場所を変更したらコントロールも紙との位置を維持したまま移動するというわけだ。
    - `StackPanel`は特定の方向にコントロールを並べていくだけ。
    - `DockPanel`は特定の方向にドッキングするパネル。特筆すべきことはないが、`DockPanel`の中に入れた最後の要素が残りの領域を占有するという特徴がある。つまりXAMLの記述順序がレイアウトに影響するというわけだ。[わかりやすい文献](https://anderson02.com/cs/wpf/wpf-29/)が山ほどある。
    - `WrapPanel`は折り返し可能な`StackPanel`のようなものだ。ある方向にコントロールを並べていくが、領域内に収まりきらない場合は次の行や列に折り返して表示される。
    - `UniformGrid`は超単純なグリッド(格子状)レイアウトだ。行数と列数を決めるとコントロールを同じ大きさのセルに順番に並べてくれるだけ。機能が少ない分シンプルだから結構使いどころありそうだな。
    - `Grid`は`UniformGrid`の上位版である。`UniformGrid`ではできなかったセルの大きさを細かく調整することやセルを結合することが可能になる。`Grid`の最大の特徴は他のパネルと違って**XAMLの記述順序とレイアウトが分離できる**点だ。他のパネルは書いた順に並べられていくが、`Grid`は順序をプロパティで指定する。よってレイアウトの変更も簡単に行うことができる。
- `Grid`のセルの幅はピクセル単位、割合(例: 2*)、内部のコントロールに合わせる(Auto)の3パターンで指定できる。
- `Grid`のセルの大きさは`SharedSizeGroup`というプロパティを使って他のセルや`Grid`と共有することができる。
- これらの標準的なパネルでは表現できない凝ったレイアウト(例えばコントロールを円形に並べたいとか)にしたい場合は**カスタムレイアウト**を作る必要がある。
    - 本書ではページ数はそれなりに割かれているものの断片的にしか書かれていない。ほとんど使うことなさそうだけどな。
    - カスタムレイアウトについては日本語の文献が少ないが、[この英語の文献](https://www.wpftutorial.net/CustomLayoutPanel.html)をまず読むとやるべきことがはっきりする。なるほど`Panel`から派生させて実現したいレイアウトになるようにメソッドをオーバーライドするのね。

# 5章 視覚要素
- あんまり使わないので詳細は覚えようとせずに「そんなもんがあったな～」と後から思い出せる程度に読んでおく。
- 2Dグラフィックスの要素は`ジオメトリ`、`ブラシ`、`ペン`の3つに集約される。これらを組み合わせて2Dのグラフィクスをデザインしていく。
    - ジオメトリは形状のことであり、矩形や円、直線、自由曲線(パス)が含まれる。あくまで形状であって色はブラシなどで決まる。
    - ブラシは塗りつぶしのことである。
    - ペンは形状の外形線のことである。
- WPFの設計原則に**解像度非依存**がある。ディスプレイの解像度によらずアプリケーションは同じ見た目に見えるべきだということだろう。
    - よくWPFは高DPI対応しているというのがメリットだといわれる。高DPIの問題がどのようなものかについては[この資料](https://pc-plaza.com/windows-10-scaling/)をみるとよい。最近は[WinFormsも高DPIに対応している](https://docs.microsoft.com/ja-jp/dotnet/desktop/winforms/high-dpi-support-in-windows-forms?view=netframeworkdesktop-4.8)みたいだからこの点ではWPFの優位性はないみたい。
    - WPFは1/96インチという論理ピクセルを用いて座標を表現しているらしい。つまり、実際のディスプレイのピクセル数を意識することなく開発ができるということのようだ。
- WPFで扱える色の記述方法には`sRGB`、`scRGB`、`Adobe 1998カラープロファイル`などが使えるようだ。
    - よく使う"いわゆるRGB"は`sRGB`のようだ。それぞれの記述方法で色を表現できる範囲(細かさではなく、色を表現できる幅という感じか)が違うようだ。
- ペンはジオメトリの輪郭を描くために使用する。ジオメトリはいわば頂点の集まりであって太さや色を持っていない。ペンを使ってその外形線を書いてあげる必要がある。
    - 線の端点の形状などInkscapeみたいな感じの柔軟な指定がいろいろできる。
- WPFはもちろん画像も扱うことができる。正直画像を扱うクラスは[いっぱいあってよく違いがわからない](https://qiita.com/YSRKEN/items/a24bf2173f0129a5825c)が、必要になったらまた調べればいい。
- アニメーションを使うことで動的なUIを実現できる。自前でタイマーを作り、定期的にアニメーション化したい物体のプロパティを変更するというような不細工なことをしなくてもWPFにはいろいろな便利な機能がある。
    - `Storyboard`を使うとめんどくさいアニメーションの記述を簡単にできる。コードビハインドなどにC#で記述するのではく、XAML本体にかけてしまうのがうれしい。素晴らしい[文献はたくさん](https://blog.okazuki.jp/entry/2014/08/27/214003)あるのでそちらを参照してほしい。
    - アニメーションとか実際使わないだろうと思うかもしれないが、クリックしたときにオシャレな視覚効果で動くボタンなどの小道具を作るのにも使えるようだ。[こんなこと](https://qiita.com/tera1707/items/a7fcdd95fc3120ae3c8b)をいつかやってみたい。

# 6章 データ
- WPFといえばデータバインディングである。これは見た目(ビュー)とロジック(モデル)を分離するための手法である。
    - アプリケーションの見た目はデザイナーにやってもらいたいが、内部のロジック・処理は専門的なエンジニアにやってもらいたいというような場合にお互いの作業領域があまりに干渉しすぎるとどちらか一方がボトルネックになったりして作業がしにくいことが考えられる。
    - ビューからロジックを分離すると再利用性が向上する。ロジックの中にこのボタンの見た目を…みたいな処理を書いていたら、そのロジックをほかの機能で使いたいと思ってもボタンの処理が邪魔で再利用することができない。
    - 最近流行しているアジャイル開発ではテストの自動化が重要なキーワードである。しかし、ロジックがビューに依存しているとロジックをテストしようと思ってもビューとの協調や人間の操作が必要になる場合があり、自動化が難しくなってしまう。
- まずはリソースの話。WPFは**1つのコントロール(要素)は1つしか存在できない**という原則があるようだ。そりゃあ確かにそうだ。ボタンを1つしか定義していないのにそれを複数の場所に同時に配置しようなんてことができないのは容易に想定できる。だから、以下のコードはうまくいかない。2つめの`Button`にしか`TextBox`が表示されなかった。

```xml
<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Window.Resources>
        <TextBox x:Key="sharedTextBox">おれはここだああ</TextBox>
    </Window.Resources>
    <StackPanel>
        <Button Content="{StaticResource sharedTextBox}"/>
        <Button Content="{StaticResource sharedTextBox}"/>
    </StackPanel>
</Window>
```

- `StaticResource`はリソースのオブジェクトをコピーしてリソースの設定をするが、`DynamicResource`はリソースのオブジェクトの参照を渡すようだ(そう読めた。違っていたらすみません)
    - 例えばリソースに定義された`Button`の`Background`に`StaticResource`で`SolidColorBlush`を参照した場合、後からリソースの値を変更しても`Button`の`Background`は変わらない。一方で`DynamicResource`にすると後から変更することができる。つまり、リソースの状態が常に監視された状態になるということだ。
- 私の知るデータバインディングとはリソースの話ではなく、XAMLとC#のコードを橋渡しして**データのありか**を指定する方法のことである。このデータバインディングは`ソース`と`パス`を指定する。要はどのオブジェクトの(=ソース)のどのプロパティ(=パス)を紐づける(バインディング)のかを設定する。
    - `textBox1`という名前のオブジェクトの`Text`プロパティを参照するなら`{Binding ElementName=textBox1, Path=Text}`と書く。
    - データバインディングは何かというのを一言で説明するのは非常に難しいので[先人の素晴らしい記事](https://ufcpp.net/study/dotnet/wpf_binding.html)を参照してほしい。
- データバインディングはあるプロパティに変数を代入するようなものであるが、ここでひとつ問題が発生する。
    - 代入するとなるとどうしても型を意識しなければならない。例えば`string`型のプロパティに`int`の型の値を代入することは一般にはできない。
    - データバインディングも同様で、バインディングされる側とする側の型を意識しなければならないが、これを上手に変換してくれる強力な機能として`コンバータ`がある。[このあたりの記事](https://tocsworld.wordpress.com/2014/04/20/wpf%E3%81%A7%E3%81%AEivalueconverter%E3%81%A8typeconverter/)の説明がわかりやすい。
- データバインディングで重要となるのはデータの同期である。
    - データバインディングはC#でデータソースを指定して、XAMLで表示するわけだが、どちらかの値が変更されたらもう一方にうまいこと通知してあげないと不一致が生じてしまうし、都度代入する処理みたいなものを自前で書いていたら非常に面倒である、
    - 動機をする方法として本書では3つ挙げている。(1) `INotifyPropertyChanged`を実装する (2) 変更をプロパティに報告するイベントを作成する (3) `DependencyProperty`ベースのプロパティを作成する
    - 恥ずかしながら**(2)は何のことかわからなかった**。Windows Formsなどでサポートされていると書かれているので、[このあたりの記事](https://tocsworld.wordpress.com/2014/04/14/windowsforms%E3%81%A7%E3%81%AE%E5%8D%98%E9%A0%85%E3%83%87%E3%83%BC%E3%82%BF%E3%83%90%E3%82%A4%E3%83%B3%E3%83%89%E3%81%BE%E3%82%8F%E3%82%8A/)で述べられている方法なのかもしれない。
- View(XAMLで書くやつ)とModel(データそのもの)を結びつけるのがデータバインディングだが、Model側の変更がViewに反映されるためにはModel側から通知をしてあげる必要がある。それをするのが`INotifyPropertyChanged`である。
    - WPFの極めて重要な仕組みであるにも関わらず、実現するために書かないといけないコードが妙に多い。[このあたりの記事](https://qiita.com/ledsun/items/6f4ef754e5ae2507e531)を見ると解決方法がわかる。
- XAMLはXMLをベースに作られているからXAML内にXMLのデータ構造やXPathのクエリが使用できる。[このあたりの記事](https://plaza.rakuten.co.jp/shebapg/diary/200903020000/)に使い方が書いてあるが、でもこれってどういうときに使うんだろう。
- `ItemTemplate`(リスト系のコントロールの各要素の表示を決める属性)は`DataTemplate`オブジェクトで指定するが、複数の`DataTemplate`の中からどれを使用するかを条件に応じて変更したい場合がある。これには`ItemTemplateSelector`を使用する。
- リスト系のコントロールには`IsSynchronizedWithCurrentItem`という属性があり、これを`True`にすると複数のコントロール間の値をデータバインディングによって同期することができるらしい。[いろいろ](http://pro.art55.jp/?eid=1048202)使えそうだよね。
- コレクションをソートしたりグループ化して表示したい場合は`CollectionView`を使用する。
    - あくまで表示時にソートなどの処理を行うのであって、コレクションそのものがソートされている必要はない。要はView側で簡単なデータ処理をやってしまうというわけだ。
    - 単一のコレクションから複数のViewを作れるちゃうから、Viewのためにわざわざモデル側を変更しなくてよくなる。詳しくは[このあたり](http://pro.art55.jp/?eid=1139229)を見るとよい。

# 7章 アクション
- データバインディングは**見た目**と**ロジック**を連携させる仕組みであった。一方でアクションはユーザの操作などの**入力**に対して**ロジック**がどのように反応するかに関するものである。
- まずはシンプルなイベントハンドリングの話。`Button`の`Click`イベントとかである。
    - ボタンを押すという点では`Click`や`MouseDown`のイベントがある。同じように使えるのかというとそうではない。
    - `Click`はより抽象的な概念であって、マウスクリックはもちろん、ボタンをフォーカスした状態でSpaceキーを押したような場合も含まれる。操作そのものを表しているのではなく意味を表しているといえるだろう。
    - 一方`MouseDown`は露骨に操作だ。マウスクリックという操作が行われた場合のイベントだ。
    - WPFはこのような様々なレベルの抽象度(本文中では結合と呼んでいる)のイベントを扱うことができるようにしている。
- WPFはUIの自由度がやたらと高く、ボタンの中にボタンを作ったりすることができる。したがって、これまでのWindowsアプリケーションで使用されるようなイベント(CLRイベントというらしい)では対処しきれない。そこで、WPFではルーティングという仕組みが用意されていてイベントを自由自在に操れるようになっている。
- イベントは3種類ある。`直接イベント`と`バブルイベント`と`トンネルイベント`である。[詳細はここ](https://atmarkit.itmedia.co.jp/ait/articles/1008/03/news097_4.html)を見てほしい。
    - `直接イベント`はCLRイベントとほとんど同じらしい。イベントが発生したらその発生源のイベントハンドラのみ実行される。
    - `バブルイベント`は発生源の要素から出発して、上位の要素に向かって広がっていくようにハンドラが実行されていく。例えば`Window`の中に`GroupBox`があり、その中に`Button`があったとして`Button`をクリックしたら`Button`→`GroupBox`→`Window`の順にイベントハンドラが連鎖的に呼び出される。
    - `トンネルイベント`は最上位の要素から発生源の要素に向かって穴を掘り起こしていくようにハンドラが実行されていく。上の例でいえば`Window`→`GroupBox`→`Button`の順にイベントハンドラが連鎖的に呼び出される。
- `トンネルイベント`はかなり特殊な感じがする。なんてったって一番最初に発火するのが一番遠いところだからだ。`トンネルイベント`は接頭辞に`Preview`がついていて、ボタンがクリックされたことを上位の要素で打ち消したいときなどに使用する。
- 次に`コマンド`である。WPFの代表的な機能であるデータバインディングからわかるように、WPFでは**見た目**と**ロジック**をなるべく分離する。XAMLを見た目を作るUI要素を定義できるだけでなく、UI要素を操作したときにどういったイベントを発生させるかも定義できる。
    - だが、イベントハンドラである関数名をXAML上に書いてしまうのは見た目がロジックに干渉しているといえないか？
    - イベントハンドラは特定のシグネチャ(引数の数、型など)を持っていなきゃいけないが、それも考慮してXAMLを記述しなきゃいけないのは見た目とロジックの分離という点では正しくないのではないか？
    - 上記のような問題を解決するのが`コマンド`である。
    - というものの、本書に書かれているコマンドの説明はXAMLちょっと難しい。まずは[ここの記事](https://marikooota.hatenablog.com/entry/2017/05/30/234258)でコマンドはまずもってどんなものかを把握してから、「[WPF実践](http://kisuke0303.sakura.ne.jp/blog/wordpress/wp-content/uploads/2016/08/4843696230c1698ad8ff7d086b998344.pdf)」などを読むとよい。
- `トリガ`はプロパティの値の変化が発生したときにUIの見た目を変更する機能である(おそらく見た目だけじゃないのだろうけど)。
    - マウスオーバーでボタンの色を変えたり、数値の入力値に応じて画面表示を変更したりすることができる。

# 8章 スタイル
- WPFはかなりWebに影響を受けている。HTMLとCSSの関係のように画面の構成要素とそのスタイルを分離することができる。 
- スタイルの適用には優先順位がある。[このMicrosoft Docs](https://docs.microsoft.com/en-us/dotnet/desktop/wpf/properties/dependency-property-value-precedence?view=netdesktop-6.0)や[この記事](http://tawamuredays.blog.fc2.com/blog-entry-11.html)でも述べられている。実際にサンプルを動かしてみたほうが早い。
- 過去のWindowsのUI風のテーマやサードパーティの`テーマ`を適用することができる。さらにテーマをベースとして色合いなどをユーザがカスタマイズ可能にする`スキン`の仕組みも実現することができる。
- アプリケーションの外観は一貫性が最も重要である。同じアプリケーション内で見た目がコロコロ変わる(本書ではこれをフランケンシュタインアプリケーションと表現している)
    - 見た目にこだわるなら全部のコントロールについて見た目をこだわるべきだ。ボタンはめちゃくちゃリッチな感じの見た目だけど、スライドバーは標準的なダサいやつだとダメである。

# 付録
- スレッドやユーザの入力に関することが述べられているが、とりあえず読まなくていいだろう…