.NET MAUI中Entry与Stepper绑定同一数据源不同步问题
你的问题核心在于ItemSold模型没有实现属性变更通知机制,导致Entry和Stepper绑定的amount值无法同步更新。以下是具体的修复步骤:
1. 改造ItemSold模型,实现属性变更通知
MAUI Community Toolkit提供的ObservableObject基类和[ObservableProperty]特性,可以快速实现INotifyPropertyChanged接口,让属性变化自动通知UI。
修改ItemSold类:
using CommunityToolkit.Mvvm.ComponentModel; public partial class ItemSold : ObservableObject { public string name { get; set; } public string description { get; set; } public string unitName { get; set; } public double unitPrice { get; set; } // 使用ObservableProperty自动生成可观察属性,自带变更通知 [ObservableProperty] private int amount = 1; }
注:
[ObservableProperty]会自动生成名为Amount的公共属性(首字母大写),并在值变化时触发PropertyChanged事件,所有绑定该属性的控件都会同步更新。
2. 修正XAML中的绑定配置
调整Entry的绑定
Entry的Text是字符串类型,Amount是整数类型,需要明确双向绑定并处理类型转换:
<Entry HorizontalOptions="Start" VerticalOptions="Center" WidthRequest="150" Grid.Column="1" BackgroundColor="White" Text="{Binding Amount, Mode=TwoWay, StringFormat='{0}'}" />
Mode=TwoWay:确保Entry输入的内容能反向更新Amount属性StringFormat='{0}':保证整数转字符串时格式正确,避免转换异常
调整Stepper的绑定
Stepper的Value是数值类型,直接绑定到Amount即可,同时注意ViewModel中的inf要改为属性(绑定只能针对属性,不能是字段):
<Stepper Grid.Column="2" Value="{Binding Amount, Mode=TwoWay}" Increment="1" Minimum="0" Maximum="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:InvoiceViewModel}}, Path=Inf}" />
3. 修正ViewModel中的字段为属性
将ViewModel中的inf字段改为公共属性:
// 原字段 // public int inf = int.MaxValue; // 修改为属性 public int Inf { get; } = int.MaxValue;
4. 调整AddToInvoice方法中的实例赋值
因为[ObservableProperty]生成的是Amount属性,添加商品到购物车时赋值给该属性:
[RelayCommand] private void AddToInvoice(Item item) { if (item.unitPrice is null) { return; } var itemSold = new ItemSold { name = item.name, description = item.description, unitName = item.unitName, unitPrice = (double)item.unitPrice, Amount = 1 // 赋值给自动生成的公共属性 }; ItemsSold.Add(itemSold); }
原理说明
之前的ItemSold是普通类,amount是普通字段/属性,修改时不会通知UI控件。当你在Entry输入5时,Entry临时存储了这个值但未同步到ItemSold;点击Stepper时修改的是ItemSold原本的默认值1,导致两者显示不同。实现INotifyPropertyChanged后,Amount属性的任何变化都会同时通知Entry和Stepper,确保两者始终共享同一值。
内容的提问来源于stack exchange,提问作者SK99

