MVVM模式下仅点击保存按钮更新Observable Object的问题
解决方案:点击保存才更新ObservableObject对象
问题核心是当前UI直接绑定到原Customer对象的属性,双向绑定会实时同步UI修改到原对象,导致未保存就修改了数据。解决思路是编辑时操作原对象的副本,点击保存再将副本数据同步到原对象。
步骤1:在ViewModel中添加副本属性并创建拷贝
修改ViewModel,添加CustomerCopy作为编辑用的副本,并在原Customer赋值时创建深拷贝:
[QueryProperty(nameof(Customer), "Customer")] public partial class CustomerDetailsEditViewModel : BaseViewModel { [ObservableProperty] public Customer customer; [ObservableProperty] public Customer customerCopy; // 当原Customer对象被设置时,创建副本 partial void OnCustomerChanged(Customer value) { if (value == null) return; // 方式1:手动复制属性(适合简单对象) CustomerCopy = new Customer { customerID = value.customerID, notes = value.notes, // 复制Customer类的其他所有属性 }; // 方式2:序列化深拷贝(适合含嵌套属性的复杂对象) // var json = System.Text.Json.JsonSerializer.Serialize(value); // CustomerCopy = System.Text.Json.JsonSerializer.Deserialize<Customer>(json); } [RelayCommand] public async Task EditCustomer() { // 将副本数据同步到原Customer对象 Customer.customerID = CustomerCopy.customerID; Customer.notes = CustomerCopy.notes; // 同步其他属性 // 执行你的更新逻辑 // Update logic in here... } }
步骤2:修改UI绑定到副本属性
将所有控件的绑定从Customer改为CustomerCopy,按钮不需要再传递参数:
<StackLayout Grid.Row="1" Orientation="Vertical" HorizontalOptions="FillAndExpand" Padding="5"> <Frame BackgroundColor="Transparent" BorderColor="DodgerBlue" Padding="5" HorizontalOptions="FillAndExpand" CornerRadius="30" > <StackLayout Orientation="Horizontal" Padding="5"> <Entry Text="{Binding CustomerCopy.customerID}" x:Name="customerIDTxt" Placeholder="رقم الهوية" PlaceholderColor="LightGray" TextColor="Black" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Margin="0,0,20,0" /> </StackLayout> </Frame> </StackLayout> <!-- 其他控件同理,替换为CustomerCopy --> <StackLayout Grid.Row="7" Orientation="Vertical" HorizontalOptions="FillAndExpand" Padding="5"> <Frame BackgroundColor="Transparent" BorderColor="DodgerBlue" Padding="5" HorizontalOptions="FillAndExpand" CornerRadius="30" > <StackLayout Orientation="Horizontal" Padding="5"> <Editor Text="{Binding CustomerCopy.notes}" PlaceholderColor="Black" TextColor="Black" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Margin="0,0,20,0" AutoSize="TextChanges" MaxLength="180" /> </StackLayout> </Frame> </StackLayout> <Button Text="حفظ" HorizontalOptions="Center" WidthRequest="200" Margin="8" Style="{StaticResource ButtonOutline}" Command="{Binding EditCustomerCommand}"/>
原理说明
- 原方式中,UI直接绑定原
Customer对象,双向绑定会在UI修改时立即更新原对象属性,导致未保存就改变了数据。 - 使用副本后,所有UI修改只会作用于
CustomerCopy,原Customer保持初始状态,直到点击保存按钮,才将副本的属性同步到原对象,再执行更新逻辑。 - 如果未点击保存就导航离开,副本会被销毁,原对象不受影响,返回页面时会重新创建新的副本,显示初始数据。
内容的提问来源于stack exchange,提问作者Mahmoud Alsheikh
相关产品推荐
相关产品推荐

