winui-code-review について
WinUI 3プロジェクト向けのコードレビュースキルです。ビルド成功後、コミット前の利用を想定し、アナライザー診断、MVVM、バインディング、アクセシビリティ、テーマ、セキュリティ、性能、国際化を確認します。
主な機能
- 01プロジェクト参照に基づくAPI確認
- 02WinUIアナライザー診断の確認
- 03MVVMとデータバインディングのレビュー
- 04アクセシビリティとテーマの監査
- 05セキュリティと性能リスクの確認
- 06国際化とローカライズの確認
活用シーン
- 01コミット前のWinUIアプリレビュー
- 02バインディングやMVVMの問題発見
- 03アクセシビリティとテーマの実践確認
- 04性能やセキュリティ上の懸念の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ microsoft/ win-dev-skills --skill winui-code-reviewインストール後、Claude Code で/winui-code-reviewを入力して読み込まれたか確認します。
同梱ファイルreferences/quality-rules.md
詳細
使用するタイミング
アプリのビルド後、コミット前にコードレビューを実施します。これにより、ビルドエラーではなく、UI テストでも確認できない品質上の問題を検出できます。つまり、コンパイルや実行はできても、誤っていたり、脆弱だったり、処理が遅かったりするパターンです。
レビュー方法
プロジェクトの XAML ファイルと C# ファイルを読み、以下の各項目を確認します。アナライザーのセットアップについては winui-dev-workflow を参照してください。インストールされていない場合は、チェックが実行されなかったことをユーザーに伝えてください。
API の不一致を報告したり、代替 API を推奨したりする前に、CLI 0.7+ の winapp find-api を使い、復元済みのアプリプロジェクトの参照に照らして確認してください。たとえば、winapp find-api members NavigationView --filter selected --json --project-dir <app-project-dir> を実行します。バッチでのプロパティチェックとプロジェクトの選択については winui-design を参照してください。マシンの SDK に基づく結果は、アプリパッケージで利用可能であることの証明にはなりません。
アナライザーは、カテゴリ分けされた 4 桁の ID を使って、WinUI 3/Windows App SDK の厳選された問題を検出します。
- WUI0xxx — UWP から WinUI 3 への API 互換性(
UwpXamlNamespace、Window.Current、CoreDispatcher、GetForCurrentView) - WUI1xxx — 移行テーブルに基づくヒント(WinAppSDK に相当 API がある UWP API、相当 API がないもの、機能領域に関するヒント)
- WUI2xxx — ランタイム/レイアウト/XAML の落とし穴(
TabViewの生コンテンツ、null 許容のバインディングパス、効果のないバインディングモード、null のConverter、AutomationIdの欠落、添付プロパティの構文) - WUI3xxx — MVVM パターン(古い
[ObservableProperty]フィールド構文) - WUI4xxx — 相互運用(
WebView2の未初期化、削除された ONNX Runtime GenAI APIWUI4101-WUI4103)
ルールの詳細については、インストール済みパッケージの診断ヘルプリンクを参照してください。モードの省略を問題として扱う前に、継承された x:DefaultBindMode と、イベント/コマンド/コンバーターの例外を確認してください。根本原因を修正してください。正当な誤検出の抑制が必要な場合は、対象を絞って理由を記録し、包括的な NoWarn ポリシーにしないでください。IL/CsWinRT の警告も有効にしておいてください。WinUI アナライザーは AOT/トリミングの分析に代わるものではありません。
MVVM の準拠
- ViewModel は
ObservableObjectを継承し、フィールドではなく[ObservableProperty]を付けた partial プロパティを使用する - コマンドには手動の
ICommand実装ではなく[RelayCommand]属性を使用する - ViewModel に UI 型(
SolidColorBrush、Visibility、BitmapImage)を含めない — これらはコンバーターまたは XAML で扱う - コードビハインドにビジネスロジックを置かない — ナビゲーション、ダイアログの調整、イベントの配線のみとする
- 非同期メソッドには
async Taskを使用し、async voidはイベントハンドラーのみに使用する -
ObservableCollection<T>を置き換えない —.Clear()を呼び出してから項目を再追加する
x:Bind とデータバインディング
- ソースの型が既知の場合は
{x:Bind}を優先する。実行時の{Binding}には正当なソースが必要であり、AOT では生成されたプロパティプロバイダーも必要となる - 動的な値では、有効な
OneWay/TwoWayモード(明示的に指定するか、x:DefaultBindModeから継承)と変更通知を使用する。包括的なモード規則を満たすためだけに、安定しているイベント/コマンド/コンバーターのバインディングを書き換えない - コンパイル済み
x:Bindを使用するDataTemplateにはx:DataTypeを指定し、Pageには指定しない -
FallbackValueなしでネストされた null 許容パス(例:ViewModel.Selected.Name)を使用しない
ネイティブ AOT/トリミング(使用する場合)
- 公開された成果物をテストする(Release での JIT 実行は AOT の検証にはなりません)。IL/CsWinRT の警告は抑制せず、修正する
- ABI をまたぐ型は partial にする。JSON とランタイムバインディングにはソースジェネレーターを使用する —
winui-packagingのreferences/sourcegen-patterns.mdを参照
アクセシビリティ
- すべてのインタラクティブなコントロール(Button、TextBox、ComboBox、ToggleSwitch、ListView、NavigationViewItem)に
AutomationProperties.AutomationIdを指定する - アイコンのみのボタンや、表示テキストのないコントロールに
AutomationProperties.Nameを指定する - クリック可能な
Border/TextBlockではなく、意味を持つコントロール(Button、HyperlinkButton)を使用する - 色だけで情報を伝えない
テーマ設定
- すべての色に
{ThemeResource}ブラシを使用します。ハードコードされた#FF0000やColor="Blue"は使用しません - タイポグラフィには組み込みスタイル(
TitleTextBlockStyle、SubtitleTextBlockStyle、BodyTextBlockStyle、CaptionTextBlockStyle)を使用します。生のFontSizeは使用しません - 余白には 4px グリッドの倍数(4、8、12、16、24、32、48)を使用します
- 角の半径には
ControlCornerRadius/OverlayCornerRadiusを使用します。値をハードコードしません - スタイルの参照には
{ThemeResource}ではなく{StaticResource}を使用します(ブラシの使用箇所を除く)
セキュリティ
- ソースコードにシークレット、API キー、トークンを含めません
- サニタイズされていないユーザー入力を使用して
Process.Startを呼び出しません - 外部入力は使用前に検証し、サニタイズします
- ユーザー入力のファイルパスを、検証せずに
File.Delete/File.WriteAllTextで直接使用しません
パフォーマンス
- 長いリストや動的リストには、
foreachを使ったStackPanelではなく、仮想化されるListView/GridViewを使用します - 常に表示されるわけではないコンテンツ(ダイアログ、セカンダリパネルなど)には
x:Loadを使用します - 重い処理は
Task.Runまたはasync/awaitを使って UI スレッド外で実行します。UI をブロックしないでください -
.Result/.Wait()/.GetAwaiter().GetResult()は使用しません。UI スレッドがデッドロックします - 破棄可能なすべてのオブジェクト(
Model、Tokenizer、InferenceSession、Generator)でusingステートメントを使用します
グローバリゼーション
- ユーザー向け文字列には、XAML で
x:Uid、C# でResourceLoaderを使用します。文字列をハードコードしません - 文字列リソースは
Strings/en-us/Resources.reswに配置します(.resxではありません) - 日付と数値の書式設定には
CultureInfo.CurrentCultureを使用します。書式をハードコードしません - レイアウトは RTL に対応させます(
FlowDirectionはルートから継承し、RTL で崩れる絶対配置は使用しません) - ユーザー向けメッセージの文字列連結は使用しません。リソース文字列とともに
string.Formatまたは補間を使用します
レビューレポート
レビュー後、次の内容をまとめます。
- 見つかった問題: ファイル、行番号、問題点をそれぞれ列挙します
- 重大度: Error(修正必須)、Warning(修正推奨)、Note(改善可能)
- 修正案: 各問題に対する具体的なコード変更を提示します
参考資料
コード例を含む詳細なルールについては、references/quality-rules.md を参照してください。パフォーマンスの詳細(x:Phase、レイアウト最適化)、セキュリティ(PasswordVault、DPAPI、WebView2 の強化)、アクセシビリティ(キーボード操作、スクリーンリーダー)、コード品質(.editorconfig、命名規則)、グローバリゼーション(x:Uid のパターン、RTL、複数形)を扱っています。