0

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>
leaf
  • 3
  • 2
  • google `xamarin mvvm ui does not update` to see many existing discussions. Try `OnPropertyChanged(nameof(ProdutosAgrupadosList));` after the change. – ToolmakerSteve Jan 22 '23 at 18:44
  • if your problem is that the list does not update when you add/remove items, then you should post the code that is **adding/removing** items – Jason Jan 22 '23 at 19:20

1 Answers1

0

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.

Liqun Shen-MSFT
  • 3,490
  • 2
  • 3
  • 11