TIPs of C# – #003. 開発時の選択:Formか?WPFか?

前提条件

OS:Windows 11 Pro
Visual Studio:Community 2022 v17.7.4
言語:C#

開発時の選択肢

Windowベースのソフトウェアを開発する場合、開発言語だけ決めるだけでは不十分です。

Microsoft社のVisual StudioでC#言語でWindows向けデスクトップアプリを作成しようとすると、下記の様な複数選択肢が提示され、選択が迫られます。

表で表すと下記の様になります。

アプリの種類フレームワーク種別フレームワークバージョン
Windows Form.NET Framework~4.8
.NET / .NET Core~.NET 7
WPF
(Windows Presentation Foundation)
.NET Framework~4.8
NET / .NET Core~.NET 7

※UWP(Universal Window Platform)という選択肢もありますが、Microsoft Storeの更新でWinFormアプリやWPFアプリも配信可能になったので、『配信のため』という理由でUWPを選ぶ必要は少なくなると思うので、ここでは省略します。

新「ストア」アプリは従来のUWPアプリに加え、Win32アプリ(WinForm/WPFなど)やWebアプリ(PWA)も登録できるようになっている。

https://forest.watch.impress.co.jp/docs/news/1366220.html

単純なアプリだとForm/WPF、フレームワークの違いがあっても見た目あまり変わりません…。

フレームワークは何を選ぶべきか?

Windows FormアプリかWPFアプリかの前に、フレームワークについて、「.NET Framework」を選ぶか「.NET」を選ぶか迷うかも知れません。

自分は昔「Formアプリは.NET Framework、WPFアプリは.NET」と言う思い込みがありました。.NET FrameworkがForm用コントロールを提供し、.NETがWPF用コントロールを提供していると誤解していました…。

フレームワークの違い

ざっくりとした違いはマイクロソフト社の下記説明が分かりやすいかと思います。

  1. .NET Framework は、.NET のオリジナル実装です。Windows で Web サイトやサービス、デスクトップ アプリなどを実行するサポートを行います。
  2. .NET は、Windows、Linux、macOS で Web サイト、サービス、コンソール アプリケーションを実行するためのクロス プラットフォームの実装です。GitHub で .NET はオープンソースです。.NET は以前 .NET Core と呼ばれていました。
https://dotnet.microsoft.com/ja-jp/learn/dotnet/what-is-dotnet-framework

また、マイクロソフト社の公式ドキュメントに、

この 2 つは多数の同じコンポーネントを共有しているため、両者でコードを共有できます。 

https://learn.microsoft.com/ja-jp/dotnet/standard/choosing-core-framework-server

とあるように、どちらのフレームワークを選んでも、作成するコードに違いはないと言えます。(生成されるバイナリは異なりますが…)

「.NET」「.NET Framework」どちらのフレームワークも下記の名前空間でほぼ同じAPIが提供されているからです。

名前空間概要
System.Windowsいくつかの重要な Windows Presentation Foundation (WPF) 基本要素クラス、WPF プロパティ システムおよびイベント ロジックをサポートする各種クラス、WPF のコアおよびフレームワークによって広範に使用されるその他の型を提供します。
System.Windows.FormMicrosoft Windows オペレーティング システムに用意されている豊富なユーザー インターフェイス機能を最大限に活用する、Windows ベースのアプリケーションを作成するためのクラスが含まれています。
参照:https://learn.microsoft.com/ja-jp/dotnet/api/system.windows, https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms

じゃあどっちでも良い?

同じコードを書けると言っても、やはり違うフレームワークであるので違いはあります。

設定方法が異なる

フレームワークによって設定方法が変わってきます。

※MSVS2019だと設定画面はどちらもほぼ同じだったりしますが…。

.NET Frameworkの制限

.NET Frameworkベースのアプリの場合、基本的にWPFのクラスへはアクセスできません。(System.Windows.XXXXXクラスへはアクセスできない)

.NETベースのアプリの場合は、設定によってWPFクラス、Formクラスへのアクセスは可能になります。(混在するとコードが複雑になってしまいますが…)

※MSVS2022の場合です。VS2019ではFormを利用する設定はなかった様に記憶しています。

この辺の設定の違いで、「Form=.NET Framework、WPF=.NET」という勘違いをしばらくしていました…。

.NETはクロスコンパイル可能?

「.NET」を使うと、FormアプリやWPFアプリを他のOSでも動かせる実行ファイルが出来そうな感じを受けますが(私はそうでした)、FormアプリやWPFアプリは『Windows用のデスクトップアプリ』であるため、他のOSで動くバイナリを生成できる訳はありません…。

なのでWindows用デスクトップアプリを作成する時にクロスコンパイルとかクロスプラットフォームとかを考える必要はないと思います。

※設定からターゲットOSを「Windows」以外を選択しようとしても「Windows」になります。

ライブラリやパッケージに依存

アプリを作ろうとするとサードパーティ製のライブラリや、Nugetのパッケージを利用する事になるかも知れません。

利用しようとしているライブラリやパッケージが特定のプラットフォームしか許容していない場合は、そちらに合わせるしかありません…。

フレームワークのバージョン

.NET/.NET Frameworkも複数バージョンに分かれていますが、古いものはサポート対象外となっているものもあるので、すべて選択できるという訳ではありません。

新しくアプリを開発するのであれば、出来るだけ新しい物か長期サポートとなっているものを選択すると良いと思います。

フレームワークの各バージョンについてはマイクロソフトの下記ページが参考になると思います。

.NET Framework のバージョンおよび依存関係

https://learn.microsoft.com/ja-jp/dotnet/framework/migration-guide/versions-and-dependencies

.NET のドキュメント

https://learn.microsoft.com/ja-jp/dotnet/fundamentals/

サポート期限(終了日)については下記。

Microsoft .NET Framework

https://learn.microsoft.com/ja-jp/lifecycle/products/microsoft-net-framework

Microsoft .NET および .NET Core

https://learn.microsoft.com/ja-jp/lifecycle/products/microsoft-net-and-net-core

Formアプリか?WPFアプリか?

個人的にはどちらでも構わないのですが(身も蓋もない)、最初に決めたものを途中で変更するというのはなかなか大変なので(できなくはないと思いますが)、最初にどちらで開発するかを決定する事は重要だと思います。

画面デザイン開発視点で選択

FormアプリとWPFアプリでは画面のデザイン開発方法が異なります。

Formアプリの画面デザイン開発

Formアプリでは主にデザイナーを使って、ツールの中から部品(コントロール)を選び、Formに貼り付け、プロパティウィンドウで属性やイベントハンドラーを設定して画面をデザインしていきます。

(もちろんデザイナを使わずに動的にコントロールを生成・配置する方法もあります)

デザイナーで作業した内容は、Form1.Designer.csというFormの部分クラスへ自動的にコードが生成されていきます。基本このソースは触る事が出来ないのでデザイナーでの操作がメインになります。

Formアプリの画面デザインで苦労するのが、画面サイズを変更した時の配置に関してでしょうか…。Resize()イベントハンドラで部品のサイズや配置を記述しなければならないという事もあります。

WPFアプリの画面デザイン開発

WPFアプリでも、デザイナーの画面は存在しますが、主にXAML(テキストデータ)を編集して、デザイナーの画面は確認用に使うという方が多いのではと思います。

Formアプリ開発メインだった人がWPFアプリ開発を始める時には、XAMLを使った画面デザインに引っかかる事があるかも知れません(自分がそうでした)。

ただ、慣れてくると画面のレイアウトやデザインの自由度が大きい事に気づきます。画面サイズ変更時のコントロールの配置もXAMLではある程度制御できます。

また、XAML関連のライブラリやパッケージも豊富に用意されているのが魅力です。

ただ、WPFで標準で用意されているWindowsコントロールには、Formアプリで利用可能なコントロールが含まれていませんので、「Formのあの部品が使いたいのに…」という事があるかも知れません(自分は何度もありました…)。

※設定やら記述方法を工夫すれば、Formコントロールを使う事は可能です。しかしあくまでFormベースのコントロールなのでWPFの良さをつぶしてしまう面もありますが…。

設計思想で選択

プログラムを習い始めると「MVCモデル」が出てくると思います。Model(ビジネスロジック)、View(画面)、Controler(制御)を出来るだけ分離して開発しましょうというものです(だったと思います)。

デスクトップアプリではPC内で表示・計算・処理が完結してしまうので、ViewもControllerもModelもごっちゃになりがちです。(サーバーアプリの様にModelが外部に用意されていれば、自然とModelは分離されますが…)

Formアプリ開発では、画面はデザイナで作成するとは言え、自動生成されたコードは制御コードと一緒のクラスに配置されるので、Viewとそれ以外を分離してMVCに当てはめるというのは困難でしょう…。

WPFアプリ開発では、画面はXAML(XML)で記述し、制御コードはC#で記述するという事になるので、画面と制御コードは言語レベルで分離されます。

制御コード・ロジックが画面と分離して後ろに(?)存在するという意味でコード・ビハインド(Code-Behind)と呼ばれたりしますね。

また、WPFではViewとModelを更に分離する(と言うか結びつきを弱める)ために、MVVM(Model-View-ViewModel)という設計思想を取り入れて開発される事が多いかなと思います。

MVVMの様な設計思想はFormアプリ開発では出来ないので、MVVMで開発したいと言うような場合はWPFアプリで開発するという事になるでしょう。

ただ、XAMLの中にちょっとしたコードを記述したり、C#で画面を制御するというのは出来てしまうので、WPFアプリ開発にしたからと言って、Model(Controller)とViewの切り分けが確実にできるとは限りませんので幻想・妄信には注意が必要です。

利用するパッケージで選択

もし、利用したいと思っているサードパーティ製のライブラリや、Nugetパッケージがあったとして、それらがFormアプリかWPFアプリのどちらかにしか対応していないとなると、おのずとどちらを選ぶかは決まってきてしまうと思います。

※あるいは、それらを使わないという選択をするか…。

実行時メモリ使用量で選択

あまり話題になっているのを見たことがありませんが、自分はWPFで開発している時に

「WPFってなんでこんなにメモリを食うんだろう?」

といつも気になります。

上記のForm/Windowにラベルを表示するだけのアプリを作成して起動するだけでも、下記の様なメモリ量の差が発生します。(いずれもAnyCPU-Release、オプションはデフォルトのまま)

「.NET」を選択するとややメモリ使用量は増える傾向にありますが、FormアプリとWPFアプリのメモリの使用量は文字通り桁違いです。

WPFアプリのメモリ使用量を減らす方法や設定を探していますが、今のところ見つけられていません…。

ターゲットとなるPCのメモリ搭載量が少なく、少しでも軽いアプリを作りたいのであれば、Window Formアプリでの開発を選択するという事になるかも知れません。

自分の力量に応じて…

例えばプログラム開発の期間が決まっている場合、自分の勝手知ったる開発方法であれば、スケジュールを立てるのも、躓いた時の情報収集もある程度スムーズにいくと思います。「間に合わない!!」となれば、最終的にはど根性で…という事も可能と言えば可能です。

しかし、まったく触った事もない、開発経験のない方法で開発しようとすると、まずそれを知る事から初めないといけなくなります。それが、どれくらいかかるのかわからずスケジュールも立てづらいですし、躓いた時に情報収集しようとしても、そもそも知らない単語で意味も分からないと調べようがなく、どうしようもなくなったとしても、知らない事・やり方が分からない事はど根性では解決できません…。

なので、自分の力量に応じて選択するという事もありだと思います。

ただ、いつまでも「自分はそれは知らないので開発できない」と言うのは、自ら選択肢をなくしている事になるので、新しい開発方法を学習しておく事も重要だと思います。

要求仕様から選択

何を基準に選ぶのかをいろいろと書いてきましたが、お仕事でソフトウェアを開発する場合には、要求仕様に開発を何で行うかが指定してあれば、それに従う必要があるでしょう。

ただ、稀に発注側が「何となく…」「他のプロジェクトを真似て…」と明確な意図があって指定しているのではない場合もあるので、他の仕様を鑑みて他の種類・フレームワークが良さそうであれば、発注元に相談しても良いとは思います。


まとめ

Formアプリ・WPFアプリのどちらを、そしてどのフレームワークを選択するかについては、結局何を作るのか?作りたいのか?で選択するしかありません。

また、何を選ぶかについても、それぞれについての知識だったり、開発経験の有無で選択できるかどうかも変わってきます。

選択肢を広げるためにも、いろいろなものを見て、触れて、学習して自分の物にしていきましょう。(自戒の念を込めて…)