Xamarin MVVM Android:CheckPrice方法多次调用问题排查
问题分析
核心问题出在两处:
- 绑定了CheckBox的
PropertyChanged事件,该事件会在控件任意属性变更时触发,包括刷新列表时重新绑定Found属性的场景;再加上CachingStrategy="RetainElement"缓存了旧控件实例,导致命令被多次触发。 - 使用
ObservableCollection时直接赋值替换集合,没有正确触发集合变更通知,导致刷新失效。
解决方案
1. 修正CheckBox事件绑定(解决多次调用问题)
不要绑定PropertyChanged事件,改用CheckedChanged事件——我们只关心选中状态的变更,而非控件所有属性的变化:
<CheckBox Margin="0,-21,0,0" IsChecked="{Binding Found}"> <CheckBox.Behaviors> <xct:EventToCommandBehavior EventName="CheckedChanged" Command="{Binding BindingContext.CheckPrice, Source={x:Reference List}}" CommandParameter="{Binding .}" /> </CheckBox.Behaviors> </CheckBox>
如果必须保留PropertyChanged绑定,需在命令执行时判断变更属性是否为Found:修改XAML的CommandParameter传递属性变更参数,再在业务方法中做过滤(推荐优先使用CheckedChanged方案)。
2. 修复ObservableCollection刷新失效问题
不要直接给ObservableCollection赋值,而是清空原有元素再添加新数据,确保触发集合变更通知:
首先将ViewModel中的Products改为ObservableCollection<Product>:
public ObservableCollection<Product> Products { get; } = new ObservableCollection<Product>();
然后修改RefreshList方法:
public void RefreshList() { var newProducts = App._productRepo.GetProducts(); Products.Clear(); foreach (var product in newProducts) { Products.Add(product); } }
这样CollectionView会自动感知集合变化,无需关闭页面即可刷新。
3. 额外优化:避免重复弹窗
在UpdatePrice方法中添加标记,防止同一产品重复触发弹窗:
private bool _isPromptActive; private async void UpdatePrice(Product product) { if (_isPromptActive) return; try { _isPromptActive = true; var str = await App.Current.MainPage.DisplayPromptAsync("Product Found!", "Type the price", "Save", "Cancel", keyboard: Keyboard.Numeric); if (str != null) { product.Price = Decimal.Parse(str); App._productRepo.UpdateProduct(product); RefreshList(); } } finally { _isPromptActive = false; } }
内容的提问来源于stack exchange,提问作者leaf
相关产品推荐
相关产品推荐

