😈

WinUI 3 の悪いところ

に公開1

はじめに

WinUI 3 には明確な利点があり、現在筆者は主に WinUI 3 で開発しています。

しかし一方で悪いところ(デメリット)も多々あり、WinUI 3 での開発はイライラがつのることもまた事実です。なぜ大変なのか、

  • 不可解な設計
  • 機能不足
  • バグ

の観点から整理しました。

不可解な設計

整理されていないコントロール

ListView 系

WinUI 3 には ListView のように項目を一覧表示するコントロールが複数混在しており、分かりづらいです。

  • ListView
  • ListBox
  • GridView
  • ItemsView

機能的には ItemsView が最強ですが、クラス継承に難があります。

本来は ListView を唯一かつ最強のコントロールとし、その他のコントロールは作らない設計にしたほうが、分かりやすくシンプルだったのではないでしょうか。

詳しくはこちらの記事をご覧ください。

FilePicker 系

ファイル関連ダイアログは 2 つの名前空間にほぼ同じ物が存在しており、こちらも分かりづらいです。

  • Windows.Storage.Pickers 名前空間
  • Microsoft.Windows.Storage.Pickers 名前空間

Windows.Storage.Pickers 名前空間のダイアログはバグありで、そのバグを直すのではなく、なぜか似て非なる新たな Microsoft.Windows.Storage.Pickers作られてしまいました

バグあり旧バージョンを放置して新たなクラスを設計するという斜め上過ぎる発想に驚いています。どこからそういう設計思想が出てくるのでしょうか。

詳しくはこちらの記事をご覧ください。

整理されていないプロパティー

FilePicker 系

再びファイル関連ダイアログについてですが、「開くダイアログ」と「保存ダイアログ」でフィルター(ファイルの種類)のプロパティーが異なっています。

プロパティー名が異なるだけではなく、開くのほうはフィルター名(「JPEG 画像」など)を指定できません。

WPF の頃はきちんと統一された設計になっていた気がするのですが、より新しい WinUI 3 で設計が退化してしまったのはなぜでしょうか。

Alignment 系

TextBlock にはテキストの位置を指定するプロパティーが複数あり、分かりづらいです。

新しいアプリでは HorizontalTextAlignment を使用すべきとのことですが、そもそも 2 つ同じプロパティーを別々に作らないでほしいです。

しかも、TextAlignment はデバッグ中に値を書き換えると直ちに反映されるのに、HorizontalTextAlignment は反映されない場合があります。新しい方が性能悪いとは……。

ProtectedCursor

コントロール上でのマウスカーソル形状を指定する ProtectedCursor はその名の通り protected なので、派生クラスからしか設定できません。

カーソル形状を変更させるためにわざわざ派生クラスを作成する必要があり、なぜこのような設計にしたのでしょうか。

派生できないコントロール

TextBlockToggleSwitch など、sealed になっていて派生できないコントロールがいくつかあります。

ちょっとカスタマイズして使いたいなと思ったときにできず、不便です。

さらに、ProtectedCursor とのコンボが発生すると詰みます。

機能不足

Window が貧弱

機能不足の筆頭は、UI の根幹をなす Window です。

そもそも、LeftWidth といった最も基本的ともいえるプロパティーすら備えていません。

SizeToContent もありませんし、モーダル表示もできません。コントロールから親ウィンドウを取得することもできません。

ウィンドウプロシージャーのハンドリングもできません。無い無い尽くしです。

クラス構造としては Object から直接派生しており、DependencyObject を経由していないので、依存関係プロパティーが使えません。例えば Title プロパティーでも、文字列を設定するだけなら通常のプロパティーで問題ありませんが、スタイルやアニメーションを考慮できる依存関係プロパティーが使えるほうが良かったのではという気がしています。

XAML が貧弱

WinUI 3 の XAML はジェネリックが使えない、FindAncestor が無いなど、WPF の XAML より機能が貧弱です。

さらに、Visual Studio でのプレビューもできません。デバッグ実行中は Visual Studio にプレビューされますが、WPF の頃のように実行せずともプレビューして欲しい(デザイナープレビュー)ところです。

階層系が貧弱

例えば WPF の Panel(正確には UIElement)には IsEnabled プロパティーがあり、パネルを無効化すればパネルの上に乗っているコントロールを一気にすべて無効化できました。しかし、WinUI 3 の Panel には IsEnabled がありません。

また、WPF の UIElement には IsVisible プロパティーがあり、下にあるすべてのコンテナの Visibility を考慮した表示状態を知ることができました。しかし WinUI 3 の UIElement には IsVisible プロパティーがありません。

このように、コンテナ階層の上下に関する機能が貧弱です。

その他の機能不足

コントロールとして DataGrid が無いのはかなりつらいです。

それぞれのコントロールもこちらの比較表にあるように少しずつ機能が弱かったりします。

マルチモニター関連の機能もありません。

バグ

個々のバグを見ていくとキリが無いので、本稿では数のみを見ることにします。

バグだけではなくリクエストも含めた Issue 数になりますが、数値としては以下となります。

時点 Issue 総数 未解決 解決済
2025/07/01 7,625 1,946 5,679
2026/01/01 7,837 2,042 5,795
半年間の変化 +212 +96 +116

半年で 116 個のバグを解決している一方で、未解決バグも 96 個増えています。

1 ヶ月当たり 19.3 個のバグ解決というのは、働き手が 1 人しかおらず 1 日 1 個解決しているペースです。中小企業の Issue ならともかく、Windows の基盤とも言うべき SDK の解決数としては少ないと言わざるを得ません。

仮に今後バグがまったく増えなかったとしても(そんなことあり得ませんが……)、積んであるバグを解決するのに 8 年以上かかる計算です。不可解な設計と足りない機能に悩まされる地獄の状況が 8 年以上! かなり絶望的です。

おまけ:ビルド時間

あくまで体感で具体的に検証したわけではないので余談ですが、WinUI 3 アプリのビルドはかなり時間がかかるように思います。特にリリースビルドは時間がかかります。

たまに WinForms をビルドすると爆速すぎて驚きます。C# って本来ビルド速いよなぁと遠い目になります。

おわりに

本稿で挙げたデメリットは極めて個人的な感想なので、他の方はまた別のデメリットを感じているかと思います。

みなさんが思うデメリットをコメントに書いていただければ幸いです。

確認環境

項目 環境
OS Windows 11 Pro 25H2
Visual Studio 2026 18.4.3
.NET 10.0
Template Studio for WinUI 5.5
WinUIEx 2.9.0
Windows App SDK 1.8.260317003 (1.8.6)

参考リンク

Discussion

0x5bfa0x5bfa

もしすでにご存じの場合は申し訳ないのですが、WinUI 3関連のOSSコントリビュータとして補足させていただきます。

ListView系:まず、ListViewとGridViewの機能は同等です。同じ基底クラス(ListViewBase)を継承しており、表示の仕方のみ異なります。ListBoxに関しては、ほぼ使用されていないのでいらないものと考えるのが最善かと思われます。また、ItemsViewに関して、これはWinAppSDK 1.4で追加されたListView/GidViewを置き換えることを目的にした軽量コントロールです。ちょうど、AnnotatedScrollBar(エクスプローラのギャラリービューで使われているもの)とともに開発された、エクスプローラチーム用(internal customer)に開発したものです。WinUIにはWinUI Community Callという恒例だった配信があり、ItemsViewの導入経緯などが説明されている配信も存在します。ほかにもItemsRepeaterやItemsControlなどもあり、それぞれ用途があります。
FilePicker系:これはGitHubのイシューに開発者がコメントされている通り、名前空間がWindowsから始まるAPIはWindowsのソースコード内に存在し、WinAppSDKのレポジトリにはなく、チームも違うため、WinAppSDKチームができることは新しく作ることでした(Windows.Storageについてはメンテナすらいないと聞いたことがあります)。そもそもWinAppSDKはUWP(UAP)の古いAPIを補完していくプロジェクトですのでここはまだ理にかなっていると思います。
整理されていない○○:これは設計がまず悪いのが前提として、WinRTはCOMの派生であり、COMと同様一度世に出してしまったコントロールクラスやプロパティの実装はWPFと違い、後から変更することができません。できることは新しく追加することだけです。ABI互換性を保つため、プロパティを削除すること・クラス名を変更することすらできません。
Windowが貧弱:モーダル表示はWindowクラスから直接できませんが、Window.AppWindowを通じて可能なはずです。ウィンドウプロシージャーのハンドリングについては、WinRT.Interop.WindowNative.GetWindowHandleを通じてHWNDハンドルを取得することで可能です。
XAML が貧弱:x:Bindが存在するため(BindingはリフレクションベースですのでNative AoT非対応のためお勧めしません)、FindAnscestorはWinUIのXAMLに必要ありません。ちなみに、Windows Community ToolkitにFindAnscendantFindDescendantが存在しますので、コードビハインド側で必要であれば、それを使用するのが普通です。ちなみに、MAUI等がサポートしているXAML 2009スキーマをサポートしていないところは、決定的な「WinUIの悪いところ」です。
ビルド時間:これは、WinUIのXAMLコンパイラのパフォーマンスに起因します。これはオープンソース化されていませんが、C++とC#を生成できるように実装されているため、実装のクォリティも悪いそうです。

ちなみに、WinUIはWinAppSDKの製品の一つでWinAppSDKの開発者が担当しています。昨今のCopilotブームとウェブアプリブームで私が知る限り数人でしか開発しておらず、投資が足りていない状況です。これまでソースだけ部分公開していましたが、最近OSSに向けた声明がだされ、昨今のネイティブ回帰の動きと相まって投資が集まるかもしれませんね。WinUIを担当する凄腕開発者もいますので、報われるようになれば、と思います。