EDIT: The problem seems to occour only when the list have at least one checked checkbox.
I'm using Xamarin with MVVM and i have a CollectionView of Products and a checkbox. I have a list of Products implementing INotifyPropertyChanged. By using EventToCommandBehavior i call a Command when a checkbox is checked, binding the object as a CommandParameter. This command calls a Method called CheckPrice. This method checks if the Found property of the object is true and proceeds if it meets the condition (the IsChecked of the checkbox is binded to the Checked property of the object). After this check, the object is updated and then the method RefreshList is called, this method makes the list receive a new list from the database.
The problem is, every time the list is updated (through the RefreshList method) and the Notify() method of the List set is called, the CheckPrice method is called multiple times until i click cancel on the DisplayPrompt.
This appears to happen every time i refresh the ItemsSource (the Products list on the viewmodel).
View XAML
The CollectionView on the View
<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>
ViewModel
The list of Products that acts as the ItemsSource for the CollectionView
public List<Product> Products
{
get { return produtos; }
set { produtos = value; Notify(); }
}
The method that is being called by the CheckPrice command
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();
}
}
The RefreshList method that is called everytime i add or remove something (also called on the constructor of the viewmodel)
public void RefreshList()
{
this.Products = App._productRepo.GetProducts();
}
Among a lot of things, i tried to use an ObservableCollection instead of a List implementing INotifyPropertyChanged and that solves the problem, but that way my RefreshList method won't work (i have to close the page then open it again to refresh).
CodePudding user response:
The original code was updating the entire list when i deleted or added anything to it, so there was no notify. Now i'm using ObservableCollection without replacing the entire list.