none
UWP : mise à jour d’une ListView après suppression d’un item de la liste RRS feed

  • Discussion générale

  • Bonjour, je développe une application UWP pour Windows 10 mobile.

    J’ai une ListView avec des articles provenant d’une base SQLite. Cette Listview est intégrée dans un SemanticZoom.

    Chaque ligne comporte un bouton qui lorsqu’il est cliqué, fait disparaître l’article de la ListView (un champ qui change de valeur). Ce champ est modifié dans ma base SQLite.

    Quand on clique sur le bouton d’un article de la ListView, je n’ai pas trouvé d’autre moyen pour la mettre à jour que de recharger complètement la liste. C’est très pénalisant pour l’utilisateur, qui se retrouve à chaque fois en début de liste (encore plus quand la liste est longue).

    J’ai essayé ceci :

    listBoxobj.Items.Remove(listitem);

    Mais le compilateur me retourne l’erreur suivante :

     

    Message          "System.Exception: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))\r\n   at System.Runtime.InteropServices.WindowsRuntime.IVector`1.RemoveAt(UInt32 index)\r\n   at System.Runtime.InteropServices.WindowsRuntime.VectorToListAdapter.RemoveAtHelper[T](IVector`1 _this, UInt32 index)\r\n   at System.Runtime.InteropServices.WindowsRuntime.VectorToCollectionAdapter.Remove[T](T item)\r\n   at MemoCourses.Views.Paniers.btnPanier_Click(Object sender, RoutedEventArgs e)" string

     

    Quelqu’un pourrait-il m’aider ? Merci d’avance.

    Pour info, voici quelques extraits de mon code behind :

    private void btnPanier_Click(object sender, RoutedEventArgs e)
            {
                // on sélectionne l'article qui contient le bouton cliqué
                var listitem = (sender as FrameworkElement).Tag as Panier;
                
                listBoxobj.SelectedItem = listitem;
                //
                listitem.InOut = "In";
                Db_Helper.UpdatePanier(listitem);
                //listBoxobj.Items.Remove(listitem);  => provoque l'erreur mentionnée ci-dessus
                //listBoxobjIn.Items.Add(listBoxobjIn);
                //
                majtablePanier();
                majtablePanierIn();
    
            }
    
    private void majtablePanier()
            {
                DB_PanierList = dbpaniers.GetAllPaniers(); //Get all DB Favori  
                List<GroupInfoList<object>> groups = new List<GroupInfoList<object>>();
                var query = from item in DB_PanierList
                            where (item.InOut == "Out" & item.NomListe == currentListeAchat)
                            orderby ((Panier)item).NomCat, ((Panier)item).Name
                            group item by ((Panier)item).NomCat into g
                            select new { GroupName = g.Key, Items = g };
                foreach (var g in query)
                {
                    GroupInfoList<object> info = new GroupInfoList<object>();
                    info.Key = g.GroupName;
                    foreach (var item in g.Items)
                    {
                        info.Add(item);
                    }
                    groups.Add(info);
                }
                //
                List<GroupInfoList<object>> categories = groups;
                cvsPanier.Source = categories;
                (szPanier.ZoomedOutView as ListViewBase).ItemsSource = cvsPanier.View.CollectionGroups;
            }


    samedi 14 avril 2018 12:33

Toutes les réponses

  • Bonjour,

    Avez vous essayé d'utiliser un ObservableCollection à la place d'une List?

    Cordialement Guillaume

    mardi 17 avril 2018 11:42
  • Bonjour et merci de la réponse.

    Malheureusement (et c’est de ma faute, je n’ai pas été assez précis dans mes explications), c’est plus compliqué. Je détaille donc l’architecture du process :

    La ListView listBoxobj est utilisée dans le code XAML.

    Le Binding se fait sur une StaticResource cvsPanier.

    Ce cvsPanier est défini par la ligne de code cvsPanier.Source = categories; dans la méthode majtablePanier().

    C’est là que je bloque : je ne vois pas comment ma ListView pourrait être alimentée autrement que par cette méthode, étant donné que le résultat doit être un groupe pouvant alimenter le SemanticZoom.

    Cordialement,


    mercredi 18 avril 2018 11:44
  • Bonjour,

    Voici un exemple d'utilisation d'une ObservableCollection avec semanticZoom uwp Semantic Zoom c# code-behind

    Cordialement

    jeudi 19 avril 2018 06:43
  • Bonjour, j’ai examiné attentivement l’exemple que vous m’avez donné, et…c’est exactement ce que je fais. Voici un extrait du code behind :

    ObservableCollection<Panier> DB_PanierList = new ObservableCollection<Panier>();
    
    private void majtablePanier()
            {
                DB_PanierList = dbpaniers.GetAllPaniers(); //Get all DB Favori  
                List<GroupInfoList<object>> groups = new List<GroupInfoList<object>>();
                var query = from item in DB_PanierList
                            where (item.InOut == "Out" & item.NomListe == currentListeAchat)
                            orderby ((Panier)item).NomCat, ((Panier)item).Name
                            group item by ((Panier)item).NomCat into g
                            select new { GroupName = g.Key, Items = g };
                foreach (var g in query)
                {
                    GroupInfoList<object> info = new GroupInfoList<object>();
                    info.Key = g.GroupName;
                    foreach (var item in g.Items)
                    {
                        info.Add(item);
                    }
                    groups.Add(info);
                }
                //
                List<GroupInfoList<object>> categories = groups;
                cvsPanier.Source = categories;
                (szPanier.ZoomedOutView as ListViewBase).ItemsSource = cvsPanier.View.CollectionGroups;
            }

    Je rappelle mon problème :

    Je clique sur un bouton intégré à la ligne de mon ObservableCollection (DB_PanierList) correspondant à l’article qui doit disparaître.

    Cet article n’est pas supprimé, un champ est modifié dans la table : il passe dans une autre catégorie.

    Pour qu’il n’apparaisse plus dans l’ObservableCollection, je reconstruis la source de la Listview avec la méthode majtablePanier(), qui rafraîchit complètement l’ObservableCollection et donc affiche le premier article de la liste.

    Je voudrais supprimer cette dernière étape pour que l’utilisateur reste sur la même page (un exemple : l’app Contacts de W10 mobile : quand on supprime un contact, celui-ci disparaît de la ‘’liste’’, tous les contacts situés en-dessous du contact supprimé remontent d’une ligne, ce qui est beaucoup plus ergonomique que d’afficher la ‘’liste’’ à partir du premier contact.

    J’ai donc essayé d’intervenir directement sur la ListView, mais ça ne fonctionne pas, et c’est normal.

    J’aimerais tant résoudre ce problème, merci à celui qui pourra m’aider.


    • Modifié Mani035 dimanche 22 avril 2018 07:21
    dimanche 22 avril 2018 07:16
  • Bonjour, j’ai essayé cette modif (remplacer les List par des ObservableCollection, mais je ne peux le faire qu’avec la List groups. Si je remplace la GroupInfoList info par une ObservableCollection, je ne dispose plus de la propriété info.key, qui me permets de définir mes groupes.

    ObservableCollection<GroupInfoList<object>> categories = new ObservableCollection<GroupInfoList<object>>();
    ObservableCollection<GroupInfoList<object>> groups = new ObservableCollection<GroupInfoList<object>>();
    GroupInfoList<object> info = new GroupInfoList<object>();
    
    private void majtablePanier()
    {
        DB_PanierList = dbpaniers.GetAllPaniers(); //Get all DB Favori  
        ObservableCollection<GroupInfoList<object>> groups = new ObservableCollection<GroupInfoList<object>>();
        var query = from item in DB_PanierList
                    where (item.InOut == "Out" & item.NomListe == currentListeAchat)
                    orderby ((Panier)item).NomCat, ((Panier)item).Name
                    group item by ((Panier)item).NomCat into g
                    select new { GroupName = g.Key, Items = g };
        foreach (var g in query)
        {
            info = new GroupInfoList<object>();
            info.Key = g.GroupName;
            foreach (var item in g.Items)
            {
                info.Add(item);
            }
            groups.Add(info);
        }
        categories = groups;
        cvsPanier.Source = categories;
        (szPanier.ZoomedOutView as ListViewBase).ItemsSource = cvsPanier.View.CollectionGroups;
        
    }

    Je peux donc supprimer un groupe :

    private void btnPanier_Click(object sender, RoutedEventArgs e)
            {
                // on sélectionne l'article qui contient le bouton cliqué
                var listitem = (sender as FrameworkElement).Tag as Panier;
                GroupInfoList<object> info = new GroupInfoList<object>();
                listBoxobj.SelectedItem = listitem;
                //
                listitem.InOut = "In";
                Db_Helper.UpdatePanier(listitem);
                // uniquement pour test
                int indx = categories.Count;
                categories.Remove(categories[indx - 2]);
                //listBoxobj.Items.Remove(listitem);    => proque une erreur
                // majtablePanier();
                majtablePanierIn();
            }

    Mais pas un article imbriqué dans le groupe.

    Cela me semble de plus en plus difficile. Une suggestion ? Merci.




    • Modifié Mani035 mercredi 25 avril 2018 13:38
    mercredi 25 avril 2018 13:37