【发布时间】:2023-01-21 05:54:29
【问题描述】:
编辑: 该问题似乎仅在列表至少有一个选中的复选框时才会出现。
我将 Xamarin 与 MVVM 一起使用,并且我有一个产品的 CollectionView 和一个复选框。 我有一个实施 INotifyPropertyChanged 的产品列表。 通过使用 EventToCommandBehavior,我在选中复选框时调用 Command,将对象绑定为 CommandParameter。 此命令调用名为 CheckPrice 的方法。此方法检查对象的 Found 属性是否为真,如果满足条件则继续(复选框的 IsChecked 绑定到对象的 Checked 属性)。检查后,更新对象,然后调用 RefreshList 方法,该方法使列表从数据库接收新列表。
问题是,每次更新列表(通过 RefreshList 方法)并调用列表集的 Notify() 方法时,都会多次调用 CheckPrice 方法,直到我在 DisplayPrompt 上单击取消。
每次我刷新 ItemsSource(视图模型上的产品列表)时,这似乎都会发生。
查看 XAML
视图上的 CollectionView
<CollectionView ItemsSource="{Binding Products}" x:Name="List">
<CollectionView.ItemTemplate>
<DataTemplate>
<CheckBox Margin="0,-21,0,0" IsChecked="{Binding Found}">
<CheckBox.Behaviors CachingStrategy="RetainElement">
<xct:EventToCommandBehavior
EventName="PropertyChanged"
Command="{Binding BindingContext.CheckPrice, Source={x:Reference List}"
CommandParameter="{Binding .}" />
</CheckBox.Behaviors>
</CheckBox>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
视图模型
充当 CollectionView 的 ItemsSource 的产品列表
public List<Product> Products
{
get { return produtos; }
set { produtos = value; Notify(); }
}
CheckPrice 命令调用的方法
private async void UpdatePrice(Product product)
{
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);
RefreshProd();
}
}
每次我添加或删除某些东西时调用的 RefreshList 方法(也调用视图模型的构造函数)
public void RefreshList()
{
this.Products = App._productRepo.GetProducts();
}
在很多事情中,我尝试使用 ObservableCollection 而不是实现 INotifyPropertyChanged 的 List 并解决了问题,但那样我的 RefreshList 方法将不起作用(我必须关闭页面然后再次打开它以刷新)。
【问题讨论】:
-
我不明白为什么
ObservableCollection可以解决问题,但如果可以的话,你应该使用它。当只有一个产品发生变化时,为什么需要重新加载整个数据集?似乎可以重写和简化逻辑来避免这个问题。 -
@Jason 似乎 ObservableCollection 不会在更新列表(删除/添加项目)时通知,所以问题不会发生。有没有更好的方法来安全地更新列表?正如我所说,问题似乎只是在调用列表集的 Notify() 方法时发生,所以如果我找到一种更好的方法来更新列表而不设置新列表,我相信这会有所帮助。
-
@leaf“ObservableCollection 不会在更新列表(删除/添加项目)时通知”,你的情况正好相反。
ObservableCollection在添加或删除某些内容时引发事件,而List不会这样做。这里一定有其他事情发生。使用ObservableCollection,无需每次更改时都替换整个集合。 -
再一次,当一个价格发生变化时,你为什么要更新整个列表?为什么不只更新那个项目?如果
Product实现了INotifyPropertyChanged那么 UI 应该在价格改变时自动刷新 -
那么你做错了什么。请发布
Product的代码
标签: c# android xamarin mvvm behavior