LoginSignup
15
23

More than 1 year has passed since last update.

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

Last updated at Posted at 2021-10-31

動機とか雑感とか

  • WPF+C#(特にXAML)が使いこなせていないので「エッセンシャルWPF」を買ってみて読んでみる。
  • 結構翻訳が微妙…というか無理…内容を理解して翻訳していないだろう…読み終わったら速攻でメル○リかも。
  • 写経もいいのだが分量が多いのでしんどいので、あるリポジトリにおいてあったコードを勉強に使わせてもらった。ありがとうございます!
  • この本を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は使用する名前空間の指定をしている。ここでいえばxdは名前空間名であり、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プロパティという非常に重要な機能についての言及があるが、何を言っているのかよくわからん。
    • どう考えてもこちらのページの説明がわかりやすい。
    • コントロールの形状などをむちゃくちゃカスタマイズしたい場合Templateというプロパティに形状情報などを記述するとよいということだ。

2章 アプリケーション

  • xmlnsxmlns:xは何が違うのか。これらはプロジェクト作成時に自動生成されるが、それぞれ微妙に違うURLが設定されて何がしたいのかよくわからん
    • こちらの神ページに説明が書いてある。
    • 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には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には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には特に記述はなさそうだった。試しにこの例外をわざとthrowしても普通にCatchできた。
    • この回復が不可能っていうのはどういう意味なのか結局よくわからなかった。これらの3つの例外に処理上の共通点があるというわけじゃなくて、単に発生した場合はもう実行継続しないほうがいいよってことだろうか。
  • Windowsデスクトップアプリに限らず、ユーザの設定情報を保存しておきたいことは多いだろう
    • 本書ではApplicationSettingsBaseというクラスを使用した設定の保存方法を紹介している。これは知らなかった。この神サイトではVisual Studioを使わない方法として紹介されている。なるほど。Visual StudioのGUI上で設定を作っていくのではなく、コード上でやりたい場合にとる手法なのか。
    • ただ、特別な理由がなければこの神サイトのVisual Studioを使う方法のほうがわかりやすいような気がする。
    • ほかにもXMLファイルやレジストリなどに出力する方法があるが、ファイルの管理を手動でゴリゴリやり始めると間違えて大事な設定を上書きしちゃったり、互換性が確保されなかったりといろいろ面倒なことも多い気がする。
  • 子ウィンドウを親ウィンドウの上にフローティングさせながらも、親ウィンドウを選択可能な状態にするにはOwner属性を設定する。
    • 恥ずかしながら知らなかった。このサイトにあるような効果もあるらしい。親を閉じたら子も閉じるようにするためにわざわざ通知を送ったりしていた過去があるなんて人に言えない…
  • WPFでは画面遷移(Navigation)の機能が備えられている。要はWebページみたいにハイパーリンクで他のページに移動したり、戻ったりするというようなものだ。
    • 登場人物は3名。ナビゲーションホストページジャーナルである。
    • ナビゲーションホストはブラウザのようなものでページを表示させる土台となるものである。
    • ページはブラウザに表示されるWebページのようなもので、実際のコンテンツの中身や他のページへのリンクが含まれる。
    • ジャーナルは遷移の履歴情報である。ブラウザで戻る/進むの操作をしたかったら、どういう経路で遷移しているのかを覚えておく必要がある。それがジャーナルである。履歴といったもWebページの閲覧履歴とは違って、何か一本の動線のようなイメージだ。

3章 コントロール

  • WPFのコントロールの特徴はリッチなコントロールとシンプルなプログラミング性を両立したところといえるようだ。
    • リッチとはボタンの中にさらにボタンを含むような自由度や、様々なフォントや文字色、図形を組み合わせたゴージャスな表現力のこと。
    • シンプルなプログラミングとはなるべく少ないコードで直感的にコントロールを表現できること。
  • これを実現するのにWPFではコンテンツモデルという仕組みを採用している。そのためのクラスがContentPresenterである。
    • ContentPresenterはアダプターみたいなものだ。コントロールの上にContentPresenterというなんでも固定できるアダプターを取り付けることでその上に文字を置くのもよし、画像を置くのもよし、複数の要素を置くのもよしというような感じに上に載るものを抽象化できる装置であると読めた。
    • ContentPresenterのことを本書では"馬車馬"と表現しているが、それだとめっちゃ酷使されそうだが誤訳か?荷馬車?
  • ContentPresenterはボタンなどの中身が1つのものに使用し、リストなどの複数の項目を一覧表示するにはItemsPresenterを使用する。
    • ボタンの中に複数のコントロールを表示することは可能だが、あくまで表示する"キャンバス"は1つである。一方、ListBoxなどは"キャンバス"が明確に区切られている。よってItemsPresenterを使用することになる。
    • ListBoxListBoxItemという子要素の集まりである。ListBoxItemはボタンと同様にコントロールを表示する"キャンバス"は1つだけだからContentPresenterを使用する。よってListBoxの下にItemsPresenterがあり、その中には複数のListBoxItemが含まれていて、それぞれにContentPresenterがあるというような構造か。
  • コントロールの種類はコンテンツコントロールレイアウトコントロールレンダコントロールの3つ。
    • コンテンツコントロールはボタンやリストなどのこと。
    • レイアウトコントロールはStackPanelなどの他のコントロールを制御するもの。
    • レンダコントロールは画面上にピクセルを表示するものである。例えば画像とか矩形とか。
  • ここまではコントロールの中に何を描くかだったが、次はコントロールの見た目の話だ。当然、何を書くか見た目の一部であるから、より上位の概念を考えることになる。
    • コントロールの見た目はコントロールのプロパティControlTemplateで設定する。ControlTemplateの中にボタンの外形や枠などの見た目の情報や、前述のContentPresenterなどを階層構造に記述していく。これをVisualTreeと呼ぶことがある(?)ようだ。
    • ControlTemplateについてはこれこれなどの文献のほうがわかりやすい。
    • 知らなかったがXAMLではなく、コードでControlTemplateを記述する方法もあるようだ。まあわからんでもない内容だがXAMLのほうが階層がはっきりしていて好み。
    • ControlTemplateを使うと名前の通りテンプレ化することができる。つまりボタンの見た目を簡単に統一することができる。そういった点でいうと、このページに書いてあるようにリソースにControlTemplateを書く方法が最高にクールだと思う。
  • ItemsControlはリストのように複数の項目からなるリストである。ここの最高に明快な解説のとおり、普通にリストのソースにコレクションを指定するだけでは全然使い物にならないリストである。様々な属性を設定しながらリストをリッチにしていく必要がある。
    • 上で紹介した記事と同じ作者だとおもうけど「WPF実践」の6章の説明がわかりやすい。
  • なんちゃらTemplateが一体どこに効いてくるのか、どんな書き方をすればいいのかは難しい。上記の「WPF実践」もわかりやすいが、こちらの記事もあわせて読んで実際に何かコントロールを作ってみるとわかりやすい。
    • DataTemplateControlTemplateのどちらを使うべきなのか迷うことが多い。この記事とかこの記事がわかりやすい。カスタマイズをしたいならControlTemplate、シンプルに行きたいならDataTemplateという感じか。
  • 訳者の人には悪いが全体的にヒドい訳だ。英単語をそのまま翻訳して、英語の語順を日本語のものに直しただけというような印象すら受ける。本当に内容を理解して訳したのか疑問だ。
  • WPFにはほかにも様々なコントロールがある。InkCanvasなんてめちゃくちゃ面白そうだが、一生使うことはないんだろうなあ。

4章 レイアウト

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

5章 視覚要素

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

6章 データ

  • WPFといえばデータバインディングである。これは見た目(ビュー)とロジック(モデル)を分離するための手法である。
    • アプリケーションの見た目はデザイナーにやってもらいたいが、内部のロジック・処理は専門的なエンジニアにやってもらいたいというような場合にお互いの作業領域があまりに干渉しすぎるとどちらか一方がボトルネックになったりして作業がしにくいことが考えられる。
    • ビューからロジックを分離すると再利用性が向上する。ロジックの中にこのボタンの見た目を…みたいな処理を書いていたら、そのロジックをほかの機能で使いたいと思ってもボタンの処理が邪魔で再利用することができない。
    • 最近流行しているアジャイル開発ではテストの自動化が重要なキーワードである。しかし、ロジックがビューに依存しているとロジックをテストしようと思ってもビューとの協調や人間の操作が必要になる場合があり、自動化が難しくなってしまう。
  • まずはリソースの話。WPFは1つのコントロール(要素)は1つしか存在できないという原則があるようだ。そりゃあ確かにそうだ。ボタンを1つしか定義していないのにそれを複数の場所に同時に配置しようなんてことができないのは容易に想定できる。だから、以下のコードはうまくいかない。2つめのButtonにしかTextBoxが表示されなかった。
<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はリソースのオブジェクトの参照を渡すようだ(そう読めた。違っていたらすみません)
    • 例えばリソースに定義されたButtonBackgroundStaticResourceSolidColorBlushを参照した場合、後からリソースの値を変更してもButtonBackgroundは変わらない。一方でDynamicResourceにすると後から変更することができる。つまり、リソースの状態が常に監視された状態になるということだ。
  • 私の知るデータバインディングとはリソースの話ではなく、XAMLとC#のコードを橋渡ししてデータのありかを指定する方法のことである。このデータバインディングはソースパスを指定する。要はどのオブジェクトの(=ソース)のどのプロパティ(=パス)を紐づける(バインディング)のかを設定する。
    • textBox1という名前のオブジェクトのTextプロパティを参照するなら{Binding ElementName=textBox1, Path=Text}と書く。
    • データバインディングは何かというのを一言で説明するのは非常に難しいので先人の素晴らしい記事を参照してほしい。
  • データバインディングはあるプロパティに変数を代入するようなものであるが、ここでひとつ問題が発生する。
    • 代入するとなるとどうしても型を意識しなければならない。例えばstring型のプロパティにintの型の値を代入することは一般にはできない。
    • データバインディングも同様で、バインディングされる側とする側の型を意識しなければならないが、これを上手に変換してくれる強力な機能としてコンバータがある。このあたりの記事の説明がわかりやすい。
  • データバインディングで重要となるのはデータの同期である。
    • データバインディングはC#でデータソースを指定して、XAMLで表示するわけだが、どちらかの値が変更されたらもう一方にうまいこと通知してあげないと不一致が生じてしまうし、都度代入する処理みたいなものを自前で書いていたら非常に面倒である、
    • 動機をする方法として本書では3つ挙げている。(1) INotifyPropertyChangedを実装する (2) 変更をプロパティに報告するイベントを作成する (3) DependencyPropertyベースのプロパティを作成する
    • 恥ずかしながら(2)は何のことかわからなかった。Windows Formsなどでサポートされていると書かれているので、このあたりの記事で述べられている方法なのかもしれない。
  • View(XAMLで書くやつ)とModel(データそのもの)を結びつけるのがデータバインディングだが、Model側の変更がViewに反映されるためにはModel側から通知をしてあげる必要がある。それをするのがINotifyPropertyChangedである。
    • WPFの極めて重要な仕組みであるにも関わらず、実現するために書かないといけないコードが妙に多い。このあたりの記事を見ると解決方法がわかる。
  • XAMLはXMLをベースに作られているからXAML内にXMLのデータ構造やXPathのクエリが使用できる。このあたりの記事に使い方が書いてあるが、でもこれってどういうときに使うんだろう。
  • ItemTemplate(リスト系のコントロールの各要素の表示を決める属性)はDataTemplateオブジェクトで指定するが、複数のDataTemplateの中からどれを使用するかを条件に応じて変更したい場合がある。これにはItemTemplateSelectorを使用する。
  • リスト系のコントロールにはIsSynchronizedWithCurrentItemという属性があり、これをTrueにすると複数のコントロール間の値をデータバインディングによって同期することができるらしい。いろいろ使えそうだよね。
  • コレクションをソートしたりグループ化して表示したい場合はCollectionViewを使用する。
    • あくまで表示時にソートなどの処理を行うのであって、コレクションそのものがソートされている必要はない。要はView側で簡単なデータ処理をやってしまうというわけだ。
    • 単一のコレクションから複数のViewを作れるちゃうから、Viewのためにわざわざモデル側を変更しなくてよくなる。詳しくはこのあたりを見るとよい。

7章 アクション

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

8章 スタイル

  • WPFはかなりWebに影響を受けている。HTMLとCSSの関係のように画面の構成要素とそのスタイルを分離することができる。
  • スタイルの適用には優先順位がある。このMicrosoft Docsこの記事でも述べられている。実際にサンプルを動かしてみたほうが早い。
  • 過去のWindowsのUI風のテーマやサードパーティのテーマを適用することができる。さらにテーマをベースとして色合いなどをユーザがカスタマイズ可能にするスキンの仕組みも実現することができる。
  • アプリケーションの外観は一貫性が最も重要である。同じアプリケーション内で見た目がコロコロ変わる(本書ではこれをフランケンシュタインアプリケーションと表現している)
    • 見た目にこだわるなら全部のコントロールについて見た目をこだわるべきだ。ボタンはめちゃくちゃリッチな感じの見た目だけど、スライドバーは標準的なダサいやつだとダメである。

付録

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
23