I have a grouped CollectionView with an ObservableCollection as ItemSource andthe list shows just fine, with the itens grouped. The problem is that the UI does not get updated when i add or remove something from the collection. I need to pop and call the ProductsPage again to see the changes.
I even tried to refresh the entire list by calling the CreateGroups method after a change, it didn't work either.
Here´s parte of the code (i removed some unrelated code so there may be some inconsistencies)
ProdutosGroup
public class ProdutosGroup : ObservableCollection<Produto>
{
public string Titulo { get; set; }
public ProdutosGroup(string titulo, ObservableCollection<Produto> produtos) : base(produtos)
{
Titulo = titulo;
}
}
ProductsViewModel
public ObservableCollection<Produto> Produtos { get; set; } //the actual list of products
public ObservableCollection<ProdutosGroup> ProdutosAgrupadosList { get; set; }//the grouped list
public ListaDeProdutosViewModel(int idListaDeProdutos)
{
PopulateList();
CreateGroups();
}
public void CarregarProdutos()
{
this.Produtos = new ObservableCollection<Produto(App._produtoRepo.GetProdutos);
}
public void CreateGroups()
{
var idsCat = Produtos.Select(x => x.IdCategoria).Distinct();
var cats = new ObservableCollection<ProdutoCategoria>();
foreach (var idCat in idsCat)
{
cats.Add(App._categoriaRepo.GetProdutoCategoriaById(idCat));
}
foreach (var item in cats)
{
ObservableCollection<Produto> produtosDaCategoria = new ObservableCollection<Produto>();
foreach (var prod in Produtos)
{
if (prod.IdCategoria == item.Id)
produtosDaCategoria.Add(prod);
}
ProdutosAgrupadosList.Add(new ProdutosGroup(item.Descricao, new ObservableCollection<Produto>(produtosDaCategoria)));
}
}
ProductsPage
<ContentPage.Content>
<Grid>
<ScrollView >
<CollectionView ItemsSource="{Binding ProdutosAgrupadosList}" x:Name="Listas" IsGrouped="true">
<CollectionView.GroupHeaderTemplate>
<DataTemplate x:DataType="models:ProdutosGroup">
<Label Text="{Binding Titulo}" FontSize="28"/>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Produto">
<Label VerticalTextAlignment="Center" Text="{Binding Nome}" FontSize="28"/>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ScrollView>
<ImageButton Padding="12" Source="BasketPlus" Grid.Row="1" Command="{Binding AddForm}" HorizontalOptions="End" WidthRequest="68" HeightRequest="68" VerticalOptions="End" CornerRadius="100" Margin="0,0,16,22" BackgroundColor="{StaticResource Verde}"/>
</Grid>
</ContentPage.Content>
If you want to add an item in a group, you could simply use the following code:
ProdutosAgrupadosList[0].Add(
new Produto
{
Nome = "and"
}); // this will add the item at the end
or
ProdutosAgrupadosList[0].Insert(1,
new Produto
{
Nome = "and"
}); // add the item after the index1 item
To remove, you could either use ProdutosAgrupadosList[0].RemoveAt(index)
or use a SwipeView which you could refer to CollectionView Context menus for more info. A simple demo using SwipeView like the following
<CollectionView.ItemTemplate>
<DataTemplate >
<SwipeView>
<SwipeView.LeftItems>
<SwipeItems>
<SwipeItem Text="Delete"
BackgroundColor="LightPink"
Command="{Binding Source={x:Reference Listas}, Path=BindingContext.DeleteCommand}"
CommandParameter="{Binding}" />
</SwipeItems>
</SwipeView.LeftItems>
<StackLayout>
<Label VerticalTextAlignment="Center" Text="{Binding Nome}" FontSize="28"/>
</StackLayout>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
That works for me based on the code in your question. For more info, you could refer to Xamarin.Forms CollectionView
Hope it works for you.