まめ - たんたんめん

備忘録 C# / WPF 多め

WPFを3年くらい使ってた人の雑記

はじめに

こんばんはー 。 ブログらしい記事?を書いてみたいと思い立ったので今日は普段業務で利用しているWPFについて掘り下げて書いてみようと思います。 今回は初学者向けの内容となりますので、十分知ってるよーって人は軽く流してください。笑

  • WPF ?
    知らない人のためにWPFとか何者なのかを簡単に説明するとWindows上で動くGUIフレームワークです。
    旧来のWinFormsに比べてリッチなデザインができたり、xamlというxmlベースのマークアップでデザインを記述していくのが特徴です。

  • WPF を使ったプロダクト
    WPF を使って作られているソフトウェアで有名なものだとVisualStudio や SoureTreeなんかがありますね。

  • どんなものが作れる?
    慣れればこんな感じのGUIアプリ程度であれば1〜2日でサクッと作れます。

  • ポケモンのステータス計算ツール(趣味です)

https://github.com/p4j4dyxcry/PokeBrowser

  • 以前ブログサンプル用に作ったツール

https://github.com/p4j4dyxcry/YiSA.FontAwesome5.WPF

WinFormに比べて新しい技術とはいえ、2006年ごろの技術で今となってはWPF自体もかなりレガシーなのかもしれません。

WPF をこれから始めたい人へ

xaml系の経験が無いならばラーニングコスト(初期学習コスト)は結構高いです。
実際に何人かに業務でWPFを教えましたが皆さんやはり苦戦しながら覚えていっています。 特に最初の難関になるのがxamlとMVVMです

  • xaml
    さらっと触れましたがxamlとはWPFのデザインの部分を書くマークアップ言語です。
    C#xaml という2つの言語を使ってGUIアプリを作っていくわけですね。
    実はxaml 使わず全部c# でできなくも無いですがあまりやる価値はないので素直にxamlを使いましょう。
    デザイナーツールがあるんだからそれを使って楽々〜とかは難しいです。
    経験上がっつりxaml手書きするパターンの方がほとんどです。 むしろデザイナーはIDEが重くなるので消してますね。

  • MVVM
    WPF関連でインターネットで調べたりするとMVVMなんていうアーキテクチャとかの説明や解説が出てきます。
    いわゆるMV〜から始まる奴ら MVC とか MVP とかの仲間で WPFではDataBindingという仕組みを使ったMVVMというパターンが主流ですね。 が、しかしこれを中途半端に理解したつもりになった始めると返って開発効率が悪くなることもあります。( もちろん使った方がいいです )
    巷ではビジネスロジックとビューは依存させずに切り離すとかxaml.cs にコードビハインドを書いてはいけない、とかCommandを使いましょうとかそんな表面だけのことを書いていますが、本質は全然違います。まぁ、そこはこの記事では掘り下げません。 WPFを学習する上ではまずはコードビハインドなんも全然使って良いと思います。まず大事なのは慣れることですね。WPFにある程度慣れてからMVVMについて学習を進めれば良いです。
    この記事ではMVVMについて詳細な解説はしません。

WPFを使ってよかったこと

この項では私が実際に業務で使っててWPFの良い面を紹介していこうと思います。
今日はインパクトのある内容として3つだけ紹介します。

  • 1 . プロトタイピングが早い
    逆にFormとかは使ったことがないので比較はできないのですがWPFxamlを使ってトップダウンでUIを書いていくので直感的にレイアウトしやすいです。しかもレイアウトがそれぞれグループになるので配置換えとかも難なくできる所が好きです。VisualStudioとかを使ってるとxamlのホットリロード(プログラムの実行中に書き換えたら即反映される)もあるのでイテレーションも早いです。

  • 2 .コントロールのカスタマイズ性が高い
    コントロールというのはいわゆるボタンとかチェックボックみたいなやつです。WPFではStyleやTemplateと呼ばれる機能を使って見た目をガラッと変えることができたりします。ただ標準のコントロールなんかをカスタマイズするときは必然的に行数が増えるという欠点もありますが...
    正直標準コントロールのカスタマイズはめちゃくちゃ汎用性が落ちるのでオススメはしません。見た目とかは後述するデザイン系のライブラリを使ったり機能面だと後に書いている添付プロパティやビヘイビアを使うことをオススメします。
    これが生きるのは独自コントロールを作ったときに見た目はエンドユーザ側でカスタマイズできたりというのが大きいですね。(特にライブラリを作る側の人とかは)
    https://github.com/p4j4dyxcry/TsNode
    ちなみにこれが1年くらい前に作っていたグラフエディターのカスタムコントロールです。よかったらご参考までに見てみてください。 今見ると設計が微妙な所もありますが笑

  • 3 . モダンなUIがサクッと作れる
    デザイン系のOSSが充実してい流ので組み込みこ簡単なのでいい感じの見た目になります。 これはめちゃくちゃ良いポイントです。ディレクターとかクライアントの受けも良いですね。 nugetからパッケージを入れて数行書くだけで見た目がガラっといい感じになったり。オススメはこちら
    メトロ
    https://mahapps.com/
    マテリアルデザイン
    http://materialdesigninxaml.net/
    アイコン
    https://fontawesome.com/

WPFを使う上で意識しておきたいポイント

ちょっと初学者には難しい内容かもしれませんが大事だなと思っていることをつらつら書いてみます。

  • コントロールの機能拡張は継承より添付プロパティや、ビヘイビアを使うべし
    WPFの標準のコントロールはいまいちで、痒いところに手が届かないことが多いにあります。 そう言った場合にどの様に拡張するのが良いのでしょうか?具体的な例で解説します。
    よくあるケース 〜テキストボックス〜の例
    □テキストボックスの背景透かしを入れたい
    □入力時にインテリセンスライクな機能を入れたい
    □検索ワードでハイライトされて欲しい
    □入力クリアボタンをオーバーレイしたい
    ...
    実際に作っていく中でこの様な機能を入れたいことすぐに出てきます。
    これらを作る際にはもちろん継承やユーザーコントロールとして作ることもできますが、そういう作り方をした場合に何が問題になるのでしょうか。考えてみてください例えばテキストボックスに透かしを入れつつ、インテリセンスもだして、検索時にはハイライトされて〜...とか組み合わせを考えるととても大変になるのは想像できませんか? また、継承やユーザーコントロールとしている場合、OSSのデザインライブラリみたいなものを入れたときにオレオレコントロールだけなぜか見た目が変わらないと言ったトラブルも起こりがちです。
    実は上にあげた様な既存の機能をちょっと拡張するだけの様なことなら添付プロパティやビヘイビアと呼ばれる仕組みを使うと実現できるので継承する前にまずは考えてみましょう。

  • パフォーマンスを出すために意識すべきこと
    結構WPFは遅いとかすぐ固まるみたいな意見を聞きますが実際その通りだと思います。 深く考えずにガンガン作っていくとデータ量とかに比例してアプリケーションがどんどんモッサリしていきます。これを避けるためにどう言った所を気をつければ良いでしょうか?今日は2つのポイントを紹介しようと思います。

    • 1. UIスレッドはUIのためにある
      WPFをはじめGUIフレームワークはUIスレッドという概念があってこれはUIの更新を行うスレッドです。
      逆に言うとUI以外の処理がここに入っていくとWPFのレイアウト処理などに圧迫され、どんどんもっさりしてしまいます。UIスレッドを空けるには処理を別スレッドでバックグラウンドで処理すると言う方法が一般的なのですがそれとは別に大規模なデータを処理する際1フレームで全部処理せずに数〜数十フレームに分割すると言うアプローチもあります。

    • 2. リスト要素にユーザーコントロールは使わない
      WPF にはユーザーコントロールとカスタムコントロールという2つのアプローチで独自UIを作ることができますがこのユーザーコントロールが曲者で画面表示する際になんとBaml(Xamlのバイナリ)読み込みが走ってしまいます。数が少なければ実害はないですが、リストボックスやデータグリッドのTemplateにユーザーコントロールを指定してしまうと目に見えて画面を開く時間が遅くなります。可能であればDataTemplateやカスタムコントロールに置き換えましょう。 ... チューニングの手法は他にもありますが長くなってしまうのでこのあたりで。

さいごに

ここまでお読みいただきありがとうございます。 今日はいつもとは変わった趣旨で記事を書いてみました。いかがでしたでしょうか? 実際のところWPFはアップデートもなくどんどん廃れていっていますがしばらく業務ではWPFを利用するのでまだまだ切っても切れない縁になりそうです。引き続きWPF関連については記事を書いていくのでどうぞよろしくお願いします。