「え、WPFってまだ使ってるの?」から始まった海外エンジニア生活
「え、まだWPFやってるの?今どきWebじゃないの?」
これ、僕がアメリカで最初に言われた一言です(笑)。職場のエンジニア仲間とのランチ中、自己紹介をしていた時のことでした。
確かに、Web全盛のこの時代、WPF(Windows Presentation Foundation)はちょっと時代遅れに見えるかもしれません。XAMLでUI書いて、MVVMでロジック分けて、.NET Framework時代から続いてる技術。でも、実はアメリカでもWPFはまだまだ現役なんです。特に、**産業機器・医療・金融系の「止まっちゃいけないデスクトップアプリ」**では、むしろWPFのような安定したUIフレームワークが重宝されています。
■ 海を越えても変わらなかった「UIの奥深さ」
僕自身、日本では製造業向けの業務アプリ開発をC#とWPFでやっていました。UIの使いやすさやレスポンス、センサーやシリアル通信機器との連携など、**「派手じゃないけど、超リアルでハードな現場」**で使われるアプリです。
アメリカでも、その経験はまるごと活かせました。今僕が携わっているのは、ある研究機関の測定器コントロール用ソフトウェアのUI設計と開発。まさにWPFの独壇場です。
渡米前は正直、「WPFしかやってこなかったけど、アメリカで通用するかな」と不安でした。でも実際は逆。WPFにガチで取り組んできた自分の強みが、ニッチな領域でがっつり評価されました。
■ WPFで求められる“深さ”は世界共通
アメリカの開発現場で感じたのは、WPFに求められるレベルが日本と同じかそれ以上だということ。MVVMは基本。さらに、
- ReactiveUIやPrismなどのMVVMフレームワーク活用
- カスタムControlTemplateやDataTemplateの駆使
- DPI対応、ローカライゼーション(多言語化)対応
- パフォーマンスチューニング(遅延バインディング、仮想化)
- COM通信やWin32 APIの連携
といった、「WPFを“使う”じゃなくて、“極める”」領域ががっつり求められます。
■ ツールと開発環境の違いに驚いた話
開発環境も日本とちょっと違います。アメリカの現場では以下のようなツール構成が主流でした:
- Visual Studio 2022 (Enterprise Edition):ResharperやCodeRushなどのプラグインも導入されてる率高め
- GitHub Enterprise or Azure DevOps:CI/CDとの連携が必須
- JetBrains Rider:Macユーザーや軽量志向のエンジニアに人気
- FigmaやAdobe XDでのUIモック共有:デザイナーとの連携がWebアプリ並みに進化
WPFなのにデザインチームがFigma使ってくるなんて、日本じゃあまりなかったですよね(笑)。
■ なぜ今、WPFをやるのか
海外でもWPFを選ぶ理由は明確です。
- ハードウェアに密接に関わるUI(センサー表示やリアルタイム制御)
- 10年以上の運用を前提とした安定性
- セキュリティ・オフライン要件がある業界(政府・医療・製造)
こうした現場では、「WebよりWPFの方が向いてるよね」という判断が今も普通に行われています。
■ まとめ:WPFが「過去の技術」なんて言わせない
もちろん、BlazorやMAUIなど新しいUI技術も出てきています。でも、「現場で使われている」技術をしっかり極めることこそが、どの国でも評価される力になると僕は思っています。
アメリカでWPFやってると、周囲から「レアキャラ」扱いされることもあるけど、その分「できる人」の価値が高いんです。まさに、「技術は国境を超える」瞬間を日々感じながら仕事しています。
現場で叩き込まれたWPFの“実践力”
WPFは「古いけど奥が深い」——これはアメリカで働き始めてから、改めて実感したことです。
WPFをやっていると、よく聞かれるのが「MVVMって実際どう使ってる?」とか「そもそもViewModelって何やらせるの?」っていう話。正直、日本での経験だと、MVVMっぽいコードにしてるけど、DataContextぐらいしか使ってない…ってパターンも多かったと思います。
でもアメリカでは、「MVVMが当たり前」というより、「MVVMをどれだけちゃんとやれてるか?」が問われる場面が多いです。
■ MVVMは“アーキテクチャ”じゃなくて“会話の共通語”
今の職場では、UIまわりの話をするときに、こんなふうに会話が始まります。
Designer: “Hey, can we update the
StatusViewModelto reflect the real-time result when the calibration finishes?”Me: “Sure. I’ll bind the result to the
StatusViewviaReactiveCommand. Let me just debounce the response.”
つまり、ViewModelが会話の単位になってるんです。
WPFアプリはデザイナーとエンジニアががっつり連携する必要があるので、「どのViewModelが何を持ってるか」が明確になっていないと、チーム全体の足を引っ張ってしまいます。
■ ReactiveUIで非同期の鬼になれ
アメリカの現場で多いMVVMフレームワークは以下の通り:
- Prism:官公庁やエンタープライズ系で多い
- MVVM Light Toolkit:古いコードベースでよく見かける
- ReactiveUI:アジャイルでスピード重視の現場に人気
僕が現在使っているのは ReactiveUI。理由はただ一つ、非同期処理との相性がめちゃくちゃいいから。
例えば、こういう処理:
this.WhenAnyValue(x => x.IsConnected)
.Where(x => x)
.Subscribe(_ => FetchDeviceDataAsync().ToObservable().Subscribe());
このシンプルな書き方で、「接続済みになったらデバイス情報を非同期で取ってUIに反映」みたいなロジックが書けます。
Rx(Reactive Extensions)自体に慣れるまでは大変だったけど、UIとリアクションの組み合わせをこんなにスッキリ書けるのは感動モノです。
■ 実際にやってる設計パターン(僕の職場バージョン)
🧠 ViewModelのルール
- ビジネスロジックを絶対にViewModelに入れない(必ずServiceに分離)
- ViewModelは非同期I/Oの起点だけにする
- NavigationやPopupなどのUI制御は専用のNavigationServiceに任せる
🧱 Viewのルール
- UIロジック(ボタンの活性・無効化)はすべてBinding経由
- AnimationやTransitionも可能な限りXAML上で完結させる
- ControlTemplateを使ってLookAndFeelを統一(企業ブランド対応)
🧪 テスト戦略
- ViewModelは100%ユニットテスト対象(xUnit + Moq)
- UIレベルはAppiumやWinAppDriverでE2E自動化
■ DPI問題・高解像度対応はマストスキル
日本ではあまり意識されなかったけど、アメリカは4Kモニター標準になりつつあるので、高DPI対応は避けられません。
以下、僕が現場で取り入れてるTipsです:
- LayoutTransformではなくRenderTransformを使う
- ImageやIconはSVG or Vector形式で統一
- フォントサイズはデバイスに応じたリソース定義を用意
- UIスケーリングのテストを仮想マシン上の複数DPI環境で実施
また、WPFにはUseLayoutRoundingやSnapsToDevicePixelsなど、地味だけど重要なプロパティがあるので、**「WPFのプロパティ1つで世界が変わる」**という瞬間を何度も体験しました。
■ 国際化対応(i18n)は“仕組み”が全て
アメリカでのプロジェクトは当然**多言語対応(英語・スペイン語・中国語など)**が求められます。
以下の設計が特に評価された点です:
Resxファイルをローカライズ用に分割(各Viewごと)MarkupExtensionを活用してBinding先でローカライズキーを取得- 翻訳管理は
CrowdinとCI/CD連携(自動反映)
WPFのローカライズは地味だけど、ちゃんと設計すれば“コードいじらず翻訳反映”が可能になります。
■ 自分が実感した「WPFを極める」ってこういうこと
WPFって、やればやるほど「泥臭さと美しさのバランス」が問われるUIフレームワークだなって思います。
- 型安全なデータバインディング
- プロ仕様のUI
- 強力なカスタマイズ性
- 非同期&Reactiveな処理設計
これらを全部まとめて考えられる人は、アメリカでも数少ない「本物のWPFエンジニア」です。
落とし穴の中で出会った“本当のWPF”
「WPFに詳しいんでしょ?じゃあこれ、よろしく!」
そう言われて引き継いだプロジェクトは、.NET Framework 4.7 から .NET 6 への移行中。しかも、コードベースは10年以上前のもの。ViewとViewModelの境界はあいまいで、XAMLは巨大なUserControlに詰め込まれていて、DataContextはいつどこで切り替わっているのかも不明。正直、地雷原みたいなコードベースでした。
でも、このプロジェクトを通じて、僕は**“WPFの真の怖さと本当の美しさ”の両方**を知ることになります。
■ Case 1: 「起動しないアプリ」事件 ~ .NET 6の罠~
移行作業を進め、NuGetパッケージを置き換え、App.xaml.csを整理して「よし、ビルド通った!」と喜んだのも束の間。
アプリが起動しない。何も表示されない。エラーメッセージも出ない。
ログを見ても、出力は0行。MainWindowのインスタンスは生成されているのに、なぜか描画されない。3日かけて原因を突き止めた結果…
原因:アプリの起動に使っていた StartupUri="MainWindow.xaml" が .NET 6 では正しく動作しない構成だった。
代わりに、App.xaml.csで MainWindow = new MainWindow(); を手動で指定して Run() しないと動かないケースがあった。
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var window = new MainWindow();
window.Show();
}
このケースでは、XAMLでの起動定義がうまくマージされないことがあるらしく、Microsoftの公式GitHub issueでも似た報告が多数見つかりました(参考リンク)。
■ Case 2: UIがフリーズする ~ Dispatcher地獄 ~
ある日、アプリがUSBデバイス接続時にフリーズするというバグ報告が入りました。調べてみると、ViewModelの中で直接 Dispatcher.Invoke(...) を呼び出してUIを更新していたコードがありました。
Application.Current.Dispatcher.Invoke(() =>
{
StatusMessage = "デバイス接続完了";
});
このコードがUSBデバイスのスレッド上から実行されていたため、UIスレッドのロックを引き起こしていたんです。タイミングが悪いとデッドロックにも。
🔧 対処法
ReactiveCommandやObserveOnDispatcher()を活用して、非同期からUI更新へのルートを安全に確保Dispatcher.InvokeではなくDispatcher.BeginInvokeを使うことでロックを回避
Observable.FromAsync(() => FetchDataAsync())
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(result => StatusMessage = result);
このように Reactiveパターンを正しく活用することで、UIと非同期処理のバランスを保つことができました。
■ Case 3: Memory Leak 〜 破滅的なイベントハンドラ地獄 〜
ユーザーから「長時間使ってるとアプリがどんどん重くなる」という報告が寄せられました。タスクマネージャーを見ると、メモリが1GB以上に膨れ上がっている。
原因を調査すると、以下のようなコードが発見されました:
someButton.Click += (s, e) => { /* some logic */ };
これ、Viewが破棄されても Click イベントハンドラが解放されないまま残り、ViewModelやデータモデルまで参照が残りっぱなしになっていたのです。
🔧 対策
- イベントを登録したら、必ず解除する
- ViewModel → View方向の強い参照を避ける
WeakEventManagerやReactiveUIでイベント解放を自動化
WeakEventManager<Button, RoutedEventArgs>.AddHandler(
someButton, "Click", SomeHandler);
■ アメリカ現場で得た教訓
このようなバグやトラブルに対して、アメリカの開発現場では以下のような文化があります:
- 「誰かのせいにしない」代わりに、「誰よりも先にPull Requestを出す」
- 問題が起きたときに「誰が書いたコードか」よりも、「どう直したか」が重視される
- 「知らなかった」で済ませない。技術的負債の可視化と対応履歴が全てGitで管理
だからこそ、僕も悩んだ末に、自分のWPF知識を全面的にアップデートすることを決めました。ReactiveUIのドキュメントを読み直し、JetBrains Riderでメモリ使用量をトレースし、XAMLのベストプラクティスを再整理。
結果として、エラーの原因と対策を共有する社内ドキュメントをまとめたことで、チーム内での評価も上がり、次の新規プロジェクトのUIリードも任されることになりました。
“古くて最強”な技術がくれたキャリアと信頼
正直なところ、僕が海外に出る前、WPFにそこまでの価値があるとは思っていませんでした。
.NET 6やBlazor、MAUIといった“新しい波”がどんどん押し寄せてくる中で、「WPFしかできない自分は時代遅れなんじゃないか」と感じる瞬間も多かったです。
でも、アメリカで実際に仕事をして気づきました。
「古い ≠ 価値がない」
極めた技術は、どこでも通用する“武器”になる。
■ アメリカで評価された「職人気質のWPF力」
僕が現地のチームに加わった時、WPFのメンバーはたったの2人。どちらもUIを「動かす」ことはできるけれど、「設計する」ことに関してはまだ手探りな状態でした。
そこで僕は、以下のような改善を自ら提案し、主導しました:
- ViewModelの責務を明確にし、ReactiveUIベースのMVVMテンプレートを導入
- データバインディングやコンバーターの共通化(ロジックの重複排除)
- 高DPIやダークモード対応を含むStyleガイドの構築
- 単体テストフレームワークの提案とサンプル実装(xUnit+Moq)
最初は戸惑われましたが、1ヶ月後にはデザイナーから「あなたのXAMLは読みやすくて嬉しい」、プロジェクトマネージャーからは「リリースが安定した」と言われるようになりました。
気がつけば、社内のWPF関連のPull Requestには必ず僕がReviewに呼ばれるようになっていました。
■ 「コードを書くだけ」から「仕組みを残す」へ
アメリカでは、開発者としての評価軸が日本と少し違います。特にWPFのようなUI領域では、
「自分がいなくても再利用される仕組み」
をどれだけ残せるかが問われます。
僕がやったことは単にUIを書くことではなく:
- 「UI設計の意思決定をコードに残す」
- 「後続の人が困らないようにドキュメントを自動生成する」
- 「XAMLのサンプルコードをリポジトリに添える」
つまり、「コード+ナレッジの伝達パッケージ」としてWPFを再設計したことが、評価につながったのです。
その成果として、新プロジェクトのアーキテクトポジションを任されることになり、技術選定・UIガイドライン・人材育成まで関われるようになりました。
■ なぜ「WPFでよかった」と言えるのか
もちろん、ReactやFlutter、MAUIなど、魅力的なフレームワークはたくさんあります。でも、それでも僕がWPFを選び、誇りを持って続けている理由は3つあります。
1. 「一度書いたら10年動く」安定性
WPFは企業向け・現場向けのソフトで、とにかく壊れないことが求められます。
UIが派手じゃなくても、長期運用できるアーキテクチャ設計が評価される環境こそ、WPFの本領発揮。
2. 「業務に深く入り込める」UI体験
Webのような汎用性よりも、現場の業務フローを深く理解して、使いやすさを設計するスキルが必要です。これが面白い。
ユーザーから「このUI、ストレスがなくて助かる」と言われたときの達成感は、何にも代えがたいです。
3. 「替えがきかない」技術者としての価値
WPFはニッチですが、だからこそ「できる人」が重宝される。
実際、現地のリクルーターからも「あなたのようなWPFエンジニアはレアだから、転職市場でも強い」と言われました。
これは、新技術ではなかなか得られないポジションかもしれません。
■ 最後に:WPFを“武器”にできる人へ
WPFをやっていると、「古い」とか「マニアック」と言われることもあります。
でも、僕はWPFのおかげで、アメリカという大舞台で、技術者としての居場所と信頼を築くことができました。
この経験から学んだことは、
・選んだ技術を信じて深く潜れ
・泥臭くても現場に向き合え
・知識を仕組みに昇華させろ
・そして、それを伝え続けろ
ということです。
WPFをやっている日本の皆さん、どうか自信を持ってください。
その技術は、世界でまだまだ求められています。
そして、もしあなたが本気で極めるなら、それはきっと「誰にも真似できないキャリア」になります。

コメント