关于 maui-data-binding
maui-data-binding 是面向 .NET MAUI 开发者的绑定实践技能,涵盖 XAML 与代码绑定。内容重点包括编译绑定的配置、线程注意事项,以及性能和 AOT 相关建议。
主要功能
- 01使用 x:DataType 配置编译绑定
- 02.NET 9+ 的 C# Lambda 绑定
- 03CI 中的绑定警告处理
- 04集合变更的 UI 线程建议
- 05AOT 与裁剪安全的绑定实践
适用场景
- 01为 MAUI 页面和 DataTemplate 配置编译绑定
- 02检查 CI 构建中的绑定警告
- 03为 NativeAOT 构建选择绑定方式
安装
复制下面的命令,在终端中运行。
$
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 启用编译绑定。
仅在设置 BindingContext 的位置放置 x:DataType:
- 页面根元素 — 在此处分配
BindingContext。 - DataTemplate — 它会创建新的绑定范围。
不要在子元素上随意添加 x:DataType。在子元素上添加 x:DataType="x:Object" 来“绕过”编译绑定是一种反模式——这会禁用编译时检查,并重新引入反射。如需对单个绑定禁用编译绑定,请在该元素上使用 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或使用 lambda 的代码SetBinding)兼容修剪和 AOT。 - 对于真正静态的数据,使用
OneTime模式,以跳过变更跟踪注册。 - 避免在高频执行路径中使用复杂的转换器链——改为在 ViewModel 中预先计算值。
评论
支持 Markdown