maui-data-binding について
maui-data-bindingは、XAMLやコードでバインディングを扱う.NET MAUI開発者向けのスキルです。コンパイル済みバインディングの設定、スレッド上の注意点、パフォーマンスとAOTへの配慮を扱います。
主な機能
- 01x:DataTypeによるコンパイル済みバインディング設定
- 02.NET 9以降のC#ラムダバインディング
- 03CIでのバインディング警告への対応
- 04コレクション変更時のUIスレッド指針
- 05AOTとトリミングに安全なバインディング実践
活用シーン
- 01MAUIページとDataTemplateでコンパイル済みバインディングを設定
- 02CIビルドのバインディング警告を確認
- 03NativeAOTビルド向けのバインディング方式を選定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ davidortinau/ maui-skills --skill maui-data-bindingインストール後、Claude Code で/maui-data-bindingを入力して読み込まれたか確認します。
同梱ファイルreferences/data-binding-api.md
詳細
.NET MAUI データバインディング
冗長なバインディングモードを指定しない
デフォルトを上書きする場合に限り、Mode を明示的に設定してください。ほとんどのプロパティには適切なデフォルトが設定されています。
<Label Text="{Binding Score}" />
<Entry Text="{Binding UserName}" />
<Switch IsToggled="{Binding DarkMode}" />
<Label Text="{Binding Title, Mode=OneTime}" />
<Entry Text="{Binding SearchQuery, Mode=OneWayToSource}" />
<Label Text="{Binding Score, Mode=OneWay}" />
<Entry Text="{Binding UserName, Mode=TwoWay}" />
コンパイル済みバインディング — x:DataType の配置ルール
コンパイル済みバインディングは、リフレクションベースのバインディングより8~20倍高速です。x:DataType を使って有効にします。
x:DataType は BindingContext を設定する場所にだけ配置します。
- ページのルート —
BindingContextを割り当てる場所です。 - DataTemplate — 新しいバインディングスコープを作成する場所です。
子要素に x:DataType を散在させないでください。コンパイル済みバインディングから「抜ける」ために子要素へ x:DataType="x:Object" を追加するのはアンチパターンです。コンパイル時チェックが無効になり、リフレクションが再び使われるようになります。1つのバインディングだけを対象外にするには、その要素に x:DataType="{x:Null}" を指定してください(maui-xaml-authoring スキルも参照してください)。
<ContentPage x:DataType="vm:MainViewModel">
<VerticalStackLayout>
<Label Text="{Binding Title}" />
<Slider Value="{Binding Progress}" />
</VerticalStackLayout>
</ContentPage>
<ContentPage x:DataType="vm:MainViewModel">
<VerticalStackLayout>
<Label Text="{Binding Title}" />
<Slider x:DataType="x:Object" Value="{Binding Progress}" />
</VerticalStackLayout>
</ContentPage>
DataTemplate には必ず独自の x:DataType が必要です。
<CollectionView ItemsSource="{Binding People}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:Person">
<Label Text="{Binding FullName}" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
CI ではコンパイラ警告をエラーとして扱う
| 警告 | 意味 |
|---|---|
| XC0022 | 宣言された x:DataType にバインディングパスが見つかりません |
| XC0023 | プロパティがバインド可能ではありません |
| XC0024 | x:DataType の型が見つかりません |
| XC0025 | x:DataType を使わずにバインディングを使用しています(コンパイル済みでないフォールバック) |
<WarningsAsErrors>XC0022;XC0025</WarningsAsErrors>
.NET 9+ のコンパイル済みコードバインディング
リフレクションを使わず、完全に AOT セーフです。
label.SetBinding(Label.TextProperty,
static (PersonViewModel vm) => vm.FullName);
entry.SetBinding(Entry.TextProperty,
static (PersonViewModel vm) => vm.Age,
mode: BindingMode.TwoWay,
converter: new IntToStringConverter());
スレッドに関する注意点
MAUI は PropertyChanged を UI スレッドに自動的にマーシャリングするため、どのスレッドからでも発生させられます。ただし、バックグラウンドスレッドから ObservableCollection を直接変更(Add/Remove)すると、クラッシュする可能性があります。
// ✅ Safe for PropertyChanged
await Task.Run(() => Items = LoadData());
// ⚠️ ObservableCollection.Add — dispatch to UI thread
MainThread.BeginInvokeOnMainThread(() => Items.Add(newItem));
パフォーマンスのヒント
- コンパイル済みバインディングはリフレクションを排除するため、常に優先してください。
- NativeAOT / トリミング:リフレクションベースのバインディングはトリミングで動作しなくなります。コンパイル済みバインディング(XAML の
x:DataTypeまたはラムダを使ったコードのSetBinding)は、トリミングおよび AOT に安全です。 - 真に静的なデータには
OneTimeモードを使い、変更追跡の登録を省略してください。 - ホットパスで複雑なコンバーターチェーンを避け、代わりに ViewModel で値を事前計算してください。