2019年03月

フォームから WPF に移行して分かったメリット・デメリット

.NET Framework(C#)での開発のベースとなるフォーム(Windows Forms)と WPF(Windows Presentation Foundation)。後発の WPF の方が優れていてしかるべきなのに、登場からずいぶん経ったわりにはイマイチ普及が進んでないようにも見受けられる。使いづらいの?

というわけで、実際に 1 つのプロジェクト(ゆかりすたー METEOR)をフォームから WPF に移行したり、色々実験したりして分かった、フォームと WPF それぞれの良いところを整理してみた。

ゆかりすたー METEOR のフォームと WPF でのソースコード上の差分は GitHub の diff で確認できる。

WPF のほうが良いところ

フォームのほうが良いところ

まとめ

UI コントロールのフロー配置

まずは WPF の良いところから。

WPF では、ウィンドウにボタンなどのコントロールを配置する際の考え方が根本的にフォームとは違う。フォームではマウスでポチポチコントロールを置いていく(手動で位置決めをする)が、WPF は「流し込む」ようなイメージに近い。

Buttons例えばボタンを 3 つ配置する場合、右の図のように、1 つ目のボタンはウィンドウの上に自動的に吸い付く(もちろんマージン(隙間)は自由に設定できる)。2 つ目のボタンは 1 つ目のボタンに吸い付き、3 つ目のボタンは 2 つ目のボタンに吸い付く。

ボタンのサイズは自動調整される。ラベルの長さに合わせて良い感じのサイズになるのだが、そのままだと 2 つ目のボタンだけ横幅が広くて格好悪い。しかし、2 つ目のボタンに合わせて、1 つ目と 3 つ目のボタンの横幅が自動的に広がってくれるので、良い感じのレイアウトになる。

例えば多言語対応したとして、日本語だと 2 が幅広だけど英語だと 1 が幅広、なんて場合でも、言語に関わらず 3 つともサイズが揃ってくれるので便利。WPF は高 DPI 環境でもレイアウトが崩れないと言われるのも、この自動調整機能をうまく使った場合だと思う。

この考え方は非常に良いと感じた。……考え方「は」。

現実はかなり不便。WPF もフォーム同様ビジュアル開発ができるのだが、マウスでポチポチコントロールを置いても、上記は実現されない。XML(風の XAML)を手打ちしてコントロールを作っていかなければならない。ビジュアル部分はプレビュー用途で使うのが関の山。しかもエディタが重い。

グリッドへの配置をしようものなら、グリッドの何マス目なのかを地道に手打ちしていくという地獄のような作業が待っている。

タブコントロールでは、アクティブなタブページに合わせてタブコントロールのサイズが変わるので、ページを切り替えるごとにウィンドウサイズも変わるという妙な動きになってしまう。ウィンドウサイズ固定にもできるが、そうすると自動調整の恩恵を受けられず、Windows 10 では良い感じのレイアウトなのに Windows 7 だとコントロールがはみ出したりする、なんていう事態になる。

また、考え方についても、CSS でいう Flexbox に近いのではないかと思うが、Flexbox ほどオプションが豊富でもなく(均等割り付けとかはできない)、発展途上の印象がある(しかも発展が止まってる)。

テーマで見た目を変えられる

ある意味一番分かりやすいメリットがこれ。

Placeデフォルトではフォームと見た目はほとんど同じだが、例えば MaterialDesignInXamlToolkit を使えば、今風のマテリアルデザインになる。テキストボックスにプレースホルダー(入力欄に事前に表示する灰色のヒント)を入れたりとか、フォーカスが当たった際の境界線のアニメーションとか、お手軽に実現できる。

データと UI の分離と関連付け

リストボックスやコンボボックスのような選択系のコントロールにおいて、フォームではリストのアイテムを 1 つ 1 つ追加していき、リストボックスそのものがデータの塊のようになっていた。

一方で WPF では、バックデータとなるデータ群(例えば List<String>)を予め用意しておき、リストボックスに丸投げすると、全データを一気に投入できる。さらに、List<String> の内容を変更(追加・削除・入れ替え等)すると、それがちゃんとリストボックスに反映される(Items.Refresh() 関数を呼ぶ)。

データはデータ、UI は UI と分けた上でそれらを関連付けることで、考え方がすっきりする。

データグリッドがスマート

前項とも密接に関わるが、データグリッドコントロール(System.Windows.Controls.DataGrid)がフォームの時(System.Windows.Forms.DataGridView)よりもスマートになっている。

フォームの時は、行数が多いと空行を追加するだけでものすごく時間がかかっていた。それを回避するには CellValueNeeded イベントなどを駆使して必要な時にだけデータを表示する仕掛けを組まねばならなかった。

WPF では、全データを投入しておいても、行が無駄に生成されることはなく、CellValueNeeded に相当する作業を自動でやってくれる。また、条件によって行の色を自動的に変えることも可能。

ただし、フォームより大幅に後退した部分もある。代表格が「クリックされたセルの位置が(簡単には)分からない」。フォームの時は DataGridViewCellEventArgs で行列位置を知れたが、WPF ではかなり複雑な手続き(こちらの GetDataGridCellPosition() 参照)を経ないと知ることができず、まったく直感的ではない。絶対必要な事なのに、なぜこんな仕組みにしたし……。

動画系の機能が強化されている

動画からサムネイル画像を作成することが比較的簡単に行える。こちらの CreateThumb() は 100 行くらいのコード。動画のコンテナやコーデックに関わらず、扱えるものなら何でもこれでいける。

WPF の描画関連の基本思想をまだ理解できておらず(分かりやすくまとめてあるところが見当たらず……)、また、動画から画像への転写が非同期に行われるようで、その捕捉に無駄なコードを書いてしまっているので、できれば改善したい。

UI コントールの配置が簡単・速い

ここからはフォームの良いところ。

フォームは UI を作るのが簡単で速い。先に述べたように、WPF は実質 XML 手打ちなのに比べて、マウスでどんどんポチポチするだけでいい。

EditSongWindowまた、例えば右のようなウィンドウを作るとして、WPF では「どのように流し込むか」完成形を予めイメージして(もしくはどこかに書いて)から考えて、それからでないと UI を作り始められないが、フォームはもっと気軽だ。「あ、これも追加しなきゃ」と場当たり的に追加しても、後からタブオーダーを簡単に変更できたりする。

また、ラベルにアクセラレータキー(&A とか)を設定しておけば、Alt+A を押したときに隣のテキストボックスにフォーカスがちゃんと当たるなど、長年の作り込みが素晴らしい。WPF はそんなことしてくれない。

非ビジュアルコントロールもマウスで配置可能

タイマーや各種ダイアログボックスなど、ウィンドウ上に配置されるわけではないコントロール(非ビジュアルコントロール)も、フォームはマウスでポチポチ配置したり、ダブルクリックでイベントハンドラーを作ったりできる。WPF はできない。

基本的な機能がきちんと揃っている

当たり前のことが当たり前にできる。そう、フォームならね。

しかし、WPF には基本的な機能すら欠けている。

例えば、フォルダー選択ダイアログが WPF には無い。かなり高頻度で使うパーツであるが、無いものは無い。仕方が無いので、別途ライブラリを使ったりしてしのぐことになる。

また、ウィンドウの右上のボタン群のうち、最小化だけさせない、というのも、フォームならプロパティー 1 つで簡単にできる。一方で WPF は、P/Invoke で Windows API を直接叩かなくてはならない。

マイナーな機能も結構揃ってる

フォームは、マイナーめな機能も意外と揃っている。

例えば、アプリケーション独自のメッセージを処理するための機構。フォームの場合、Form.WndProc() をオーバーライドするだけで良い。一方で WPF の Window クラスにはその仕組みはないため、いくつかのパーツを組み合わせて実現する必要がある。

マルチディスプレイ環境で、ディスプレイごとの領域もフォームなら取得できる。WPF はできない(全領域なら WPF でも取得できる)。例えば、ウィンドウが 2 枚目のディスプレイにいる場合、そのディスプレイの左端に吸い付く、というような動作を、WPF ではどうやって実現するのだろうか?

勉強量が WPF より少なくて済む

シンプルに考えて、WPF でアプリケーションを作ろうとする場合、プログラミング言語である C# に加えて、画面を作るための XML である XAML を勉強する必要がある。フォームは C# だけでいい。

日本語の情報が豊富

フォームに関する日本語の情報は豊富で、DOBON.NET などのウェブサイトを見れば多くの疑問は解決する。

一方で WPF のまとまった日本語情報というのは少ない。網羅的なウェブサイトが無いのが痛い。Tips も散在はしているが数が少ないのと、せっかく見つけても「とりあえずやってみたら動いた」というような感じで汎用性に疑問のあるページも多い。一番困るのは、WPF の考え方や概念について分かりやすくまとまった情報が無いこと。一番最初に挙げた「流し込む」ような UI 配置も理解するのに時間がかかったし、描画の仕組みなどはまだまったく理解できていない。

WPF では 1 つのことをやるために C# でコードを書くやり方と XAML でコードを書くやり方の 2 通りの実装方法があるが、片方しか掲載されていないこともしばしば。

WPF は英語含めても情報が見当たらない

フォームは日本語の世界で充足するが、日本語情報の少ない WPF は海外サイトも探す必要がある。……が、海外の情報もちゃんと見つけられていない……。

まとめ

後発の WPF は、フォームよりも洗練された考え方を元に設計されていると思う。そしてその「見どころ」には確かに、WPF を使いたくなるものである。

しかし、設計が煮詰まっていないのか、あるいは実装が追いついていないのか、実装する気が失せたのかは分からないが、「見どころ」以外の部分は実用レベルに達していないと言っても過言では無い。

現状は、「見どころ」を味わうために WPF を使って地獄を見るか、それとも堅実にフォームを使って「見どころ」を楽しめない残念さをかみしめるか、の 2 択になっている気がする。

しっかりと WPF の基本思想が周知されたうえで、細部にわたり WPF の実用性が高まると良いのだが……。10 年以上前に登場したのに今がこのような状況と言うことは、今後も改善しない可能性が高いのかもしれない……。

いろんな意味で手軽に開発を進められるのは、フォームのほうだと思う。

追記:MVVM について

WPF で本格的に開発するのであれば、MVVM(Model View ViewModel)パターンと呼ばれるソフトウェアアーキテクチャの習得・活用が必須となってくる。MVVM WPF ではプログラムの考え方・構造が全く異なるため、フォームとの単純な比較はできなくなる。

本記事で使用している、フォームから WPF に移行した直後(diff 時点)でのゆかりすたー METEOR は MVVM を採用しておらず、それゆえフォームのコードとの 1 対 1 での比較がしやすくなっている。

ゆかりすたー METEOR も後期になると MVVM を採用しており、また、ゆかりすたー METEOR の後継であるゆかりすたー NEBULA は当初から MVVM WPF で開発されている。

MVVM の習得にも時間を要するため、それも含めて、手軽に開発を進められるのは、フォームのほうだと思う。

一方で、MVVM WPF では UI とそれ以外を区別してプログラムの保守性が高まるため、一定規模以上のプログラムではメリットが大きくなってくる。

実装が不十分であるところから生じる地獄についても、外部ライブラリ(Livet など)の活用によりある程度軽減される。

蛇足:個人的な好み

個人的な好みでいえば、好きな順に、
MVVM WPF > フォーム >>> MVVM ではない WPF

メインは MVVM WPF で行っており、使い捨てのツールをサッと作る時などはフォーム。

ゆかりすたー METEOR のソースコードを公開

ニコカラ動画ファイルを番組名ごとなどで整理してリスト化し、ゆかり(持ち込みカラオケ用のブラウザリクエストツール)で検索しやすくするツール「ゆかりすたー METEOR」について、ソースコードを GitHub で公開しました。
ビルドには、別途公開している「SHINTA 共通 C# ライブラリー」なども必要です。詳しくは、ゆかりすたー METEOR ソースコードのリードミー(YukaLister_Src_ReadMe_JPN.txt)をご覧ください。

併せて、SHINTA 共通 C# ライブラリーも最新版のソースコードを公開しました。


ゆかりすたー METEOR Ver 1.35 β 公開

Meteorゆかりすたー METEOR(メテオ)の新バージョン、Ver 1.35 β を公開しました。

ゆかりすたー METEOR はニコカラ動画ファイルを整理し、「ゆかり」(持ち込みカラオケ用のブラウザリクエストツール)から検索できるようにするツールです。データベースを活用することにより、タイアップしている番組名や歌手名などの付加情報を含めて整理するので、単なるファイル名検索にとどまらない高い検索性を提供することができるようになります。

ゆかりすたー METEOR は、ニコカラりすたーおよび初代ゆかりすたーの後継ソフトとして開発しています。ニコカラりすたーは一時点でのリスト化機能のみを提供していましたが、ゆかりすたー METEOR は、ゆかりと連携した高度な検索性の提供を目的に、リアルタイムでのリスト化機能と検索用データベース構築機能を提供します。

更新内容

サムネイル作成機能を搭載しました。今後のゆかりでは、検索結果にサムネイルを表示する構想があるためです。

併せて、サーバー機能の変更・強化を行いました。

その他、細かい改善をしています。今回の更新内容を含む課題対応履歴についてはこちらをご覧ください。

Windows Defender について

Windows Defender がゆかりすたー METEOR の動作に悪影響を及ぼす場合があり、エラーが発生したり、処理速度が異常に遅くなったりする例が報告されています。

ゆかりすたー METEOR を使う際は、Windows Defender を使わないことをお薦めします。

詳細についてはこちらをご覧ください。

更新・新規インストール方法

ゆかりすたー METEOR は自動更新機能を搭載しています。既にゆかりすたー METEOR をお使いの方は、ゆかりすたー METEOR を起動すると、3 日以内に更新のアナウンスが表示されます。

すぐにアップデートしたい場合は、環境設定ウィンドウのメンテナンスタブを開き、「今すぐ最新情報を確認する」ボタンをクリックすることで、アップデートを開始することができます。

Ver150to168右のようなダイアログが表示されますので、「はい。今すぐ更新します」をクリックしてください。

ゆかりすたー更新版インストール画面に案内が表示されますので、案内に従って操作をして下さい。

ゆかりすたー更新完了ほどなくして、ゆかりすたー METEOR の更新が完了します。

これから初めてゆかりすたー METEOR を使う方(新規の方)や、手動でゆかりすたー METEOR を更新したい方は、下記サイトからどうぞ。

旧作について

ニコカラりすたーおよびゆかりすたー(初代)は開発を終了しました。

今後はゆかりすたー METEOR をご利用下さい。

ゆかりすたーをリニューアル公開

Meteorゆかりすたーをリニューアルし、ゆかりすたー METEOR として、Ver 1.06 α を公開しました。

ゆかりすたー METEOR(メテオ)はニコカラ動画ファイルを整理し、「ゆかり」(持ち込みカラオケ用のブラウザリクエストツール)から検索できるようにするツールです。データベースを活用することにより、タイアップしている番組名や歌手名などの付加情報を含めて整理するので、単なるファイル名検索にとどまらない高い検索性を提供することができるようになります。

ゆかりすたー METEOR は、ニコカラりすたーの後継ソフトとして開発しています。ニコカラりすたーは一時点でのリスト化機能のみを提供していましたが、ゆかりすたー METEOR は、ゆかりと連携した高度な検索性の提供を目的に、リアルタイムでのリスト化機能と検索用データベース構築機能を提供します。

更新内容

外観にマテリアルデザインを採用しました。

出力するゆかり用リストがゆかりの新仕様に対応しました。リストから曲リクエストをする際の必要クリック数が減少しています。

ゆかり検索対象フォルダーを追加した際、今まではサブフォルダーもすべて開いた状態で表示していましたが、今回より、親フォルダーのみを表示するようにしました。サブフォルダーを見たい場合は、フォルダーの左側をクリックすることで展開されます。

その他、細かい改善をしています。今回の更新内容を含む課題対応履歴についてはこちらをご覧ください。

Windows Defender について

Windows Defender がゆかりすたーの動作に悪影響を及ぼす場合があり、エラーが発生したり、処理速度が異常に遅くなったりする例が報告されています。

ゆかりすたーを使う際は、Windows Defender を使わないことをお薦めします。

詳細についてはこちらをご覧ください。

更新・新規インストール方法

ゆかりすたー(初代)およびゆかりすたー METEOR(以降、ゆかりすたーシリーズ)は自動更新機能を搭載しています。既にゆかりすたーシリーズをお使いの方は、ゆかりすたーシリーズを起動すると、3 日以内に更新のアナウンスが表示されます。

すぐにアップデートしたい場合は、環境設定ウィンドウのメンテナンスタブを開き、「今すぐ最新情報を確認する」ボタンをクリックすることで、アップデートを開始することができます。

Ver150to168右のようなダイアログが表示されますので、「はい。今すぐ更新します」をクリックしてください。

ゆかりすたー更新版インストール画面に案内が表示されますので、案内に従って操作をして下さい。

ゆかりすたー更新完了ほどなくして、ゆかりすたー METEOR の更新が完了します。

これから初めてゆかりすたー METEOR を使う方(新規の方)や、手動でゆかりすたー METEOR を更新したい方は、下記サイトからどうぞ。

旧作について

ニコカラりすたーおよびゆかりすたー(初代)は開発を終了しました。

今後はゆかりすたー METEOR をご利用下さい。

ゆかりすたーリニューアル作業中

動画ファイルリスト化ツール「ゆかりすたー」をリニューアル中。

画面デザインを今風にアップグレード。

見た目以外の部分では(というかこちらが本命なのだが)、使用しているフレームワークを WinForm から WPF (Windows Presentation Foundation) に変更。将来的な拡張への基礎としている。

YukaLister


月別アーカイブ
記事検索
最新コメント
  • ライブドアブログ