Se connecter

Informatique

Programmation

Sujet : [UWP XAML C#] Impossible de retirer des éléments dans un StackPanel
1
Pseudo supprimé
Niveau 6
07 juillet 2020 à 12:41:03

Salut !
Je suis en train de développer une application UWP XAML en C# qui permettra de gérer les monde/textures packs/addons de Minecraft, et je bloque sur un système de StackPanel.
Le programme récupère les mondes,et leur nom en fonction des dossiers de sauvegarde du jeu, puis ajoute des custom controls au StackPanel contenant le nom des mondes, la date de création, et plus tard l'image du monde.
Bref, j'ai ajouté un bouton permettant de supprimer le monde, tout fonctionne correctement, sauf qu'après la suppression, il m'est impossible de supprimer l'élément du StackPanel (il reste dans le panel), par contre si je met à jour la page en recliquant sur le bouton permettant d'y accéder, l'élément disparaît bel et bien.
Donc ma question serait, comment supprimer dynamiquement un élément de mon StackPanel ?

Voici mon code pour le code "derrière":
https://pastebin.com/KfXeM1JF

Et celui du concepteur:
https://pastebin.com/8y2vDFeV

Voilà une image de l'application, pour que ça vous parle plus:
https://www.noelshack.com/2020-28-2-1594118416-sans-titre.png

je vous remercie d'avance pour votre aide, en espérant que quelqu'un trouve la solution et puisse me l'expliquer, parce que je suis débutant x)

boucif
Niveau 24
07 juillet 2020 à 15:00:58

Qui sait qui appel ton deletemap ?

Et c'est pas la bonne façon d'utiliser wpf, dans l'idéal il faudrait une Observablecollection binder sur un itemscontrol (ou un controle type liste quelconque)
https://wpf-tutorial.com/fr/71/les-controles-de-listes/le-controle-itemscontrol/

Ensuite tu mets simplement cette ObservableCollection à jour et ton écran se met à jour.

Si t'as besoin d'aide pour faire ça je peux t'aider.

Pseudo supprimé
Niveau 6
07 juillet 2020 à 15:55:53

Oui j'aimerai bien, merci :) A vrai dire je débute surtout avec le XAML ^^

boucif
Niveau 24
07 juillet 2020 à 17:11:31

je t'invite à lire ce cours sur le binding
https://nathanaelmarchand.developpez.com/tutoriels/dotnet/comprendre-binding-wpf-et-silverlight/

l'idée c'est de crée une liste de type observable collection https://docs.microsoft.com/fr-fr/dotnet/api/system.collections.objectmodel.observablecollection-1?view=netcore-3.1
qui sera une liste de ton objet contenant les différences infos à afficher (ton ressource box dans le cas présent)

tu auras juste à binder ton itemcontrol à cette liste et définir à l'intérieur l'itemtemplate que tu veux

Pseudo supprimé
Niveau 6
07 juillet 2020 à 17:17:26

J'ai partiellement réussi ! (En attendant le cours, j'ai fais quelques tests ^^')

Voila un extrait:
https://pastebin.com/ExAmQymH

Et en XAML:
https://pastebin.com/Yebh5iZ9

Les éléments s'ajoutent bel et bien avec la liste, mais lorsque je supprime un monde, ils ne se retirent pas. (Après que le monde est supprimé, j'utilise mapsCollection.removeAt(index).

Encore merci pour le cours ;) Je vais le lire !

boucif
Niveau 24
07 juillet 2020 à 18:20:47

Je vois que tu commences à maîtriser le binding.

Je ne vois pas ton code de suppression comment fais-tu ?

Pseudo supprimé
Niveau 6
07 juillet 2020 à 19:07:02

Ah ! j'ai oublié de le montrer parce que c'est un extrait supprimé dans Maps.xaml.cs pour des raisons de lisibilité ^^'
Alors en fait c'est une fonction DeleteMap(int index) qui prend donc en paramètre l'index de l'item qui est supprimé (En gros, à chaque fois qu'un item est instancié, je lui donne un ID, comme ça, lorsque je clique sur le bouton supprimer, il exécute une fonction contenue dans ResourceBox.xaml.cs en renvoyant l'ID qui lui a été attribué.
Ensuite, ce code est exécuté :

		
public async void DeleteMap(int index)
		{
			ContentDialog deleteFileDialog = new ContentDialog
			{
				Title = "Delete this world ?",
				Content = "If you delete this world, you won't be able to recover it. Do you want to delete it?",
				PrimaryButtonText = "Delete",
				CloseButtonText = "Cancel"
			};

			ContentDialogResult result = await deleteFileDialog.ShowAsync();

			if (result == ContentDialogResult.Primary)
			{
				try
				{
					StorageFolder mapsFolder = await StorageFolder.GetFolderFromPathAsync(folderPath);
					IReadOnlyList<StorageFolder> maps = await mapsFolder.GetFoldersAsync();

					StorageFolder MapToDelete = await StorageFolder.GetFolderFromPathAsync(folderPath + @"\" + maps[index].DisplayName);
					await MapToDelete.DeleteAsync();
					mapsCollection.RemoveAt(index);
				}
				catch (Exception ex)
				{
					ShowBox("Can't delete this world", ex.Message);
				}
			}
			else
			{
				// Do nothing
			}
		}

La variable index est l'ID dont j'ai parlé qui est renvoyé lorsqu'on clique sur le bouton. Je sais pas si c'est optimisé, mais en tout cas c'est fonctionnel, donc j'espère que le système est un minimum ingénieux x) :)

Pour en revenir au sujet, même en enlevant un élément de l'ObservableCollection avec RemoveAt(index), l'item ne disparaît pas :(
La liaison est pourtant bel et bien faite.

Bonne soirée !

boucif
Niveau 24
08 juillet 2020 à 03:13:46

Tiens je t'ai fais un petit exemple qui fonctionne.
https://github.com/youtpout/WPFBinding

Pseudo supprimé
Niveau 6
08 juillet 2020 à 10:15:08

Merci beaucoup, je vais voir tout ça :D

Pseudo supprimé
Niveau 6
08 juillet 2020 à 11:50:39

Je comprend pas, ça fonctionne toujours pas, j'ai pourtant bien fais ma liste, et mis correctement les fonctions, je t'envoie le code :/

boucif
Niveau 24
08 juillet 2020 à 13:10:07

t'aurais pas un github ou autre pour partager le code, parce qu'avoir une partie des fichier ça ne suffit pas

Pseudo supprimé
Niveau 6
08 juillet 2020 à 13:22:20

Oui, je vais partager le projet complet ^^

Pseudo supprimé
Niveau 6
08 juillet 2020 à 13:33:18

Et voilà le lien :
https://github.com/Osaxely/mc_addons_manager/tree/master

Pour lister les mondes, l'application a besoin du dossier de sauvegarde de Minecraft Bedrock (Dans Local\Packages) donc si tu as envie de faire des tests, je peux te le fournir

Pseudo supprimé
Niveau 6
08 juillet 2020 à 13:47:06

J'ai créé un dossier qui reproduit la structure du dossier de sauvegarde, tu as juste à le glisser dans TonNomUtilisateur\AppData\Local\Packages, et ça devrait aller

EDIT: Il s'appelle Microsoft.MinecraftUWP_8wekyb3d8bbwe

boucif
Niveau 24
08 juillet 2020 à 15:56:02

Hello,

voila j'ai retravaillé dessus https://github.com/youtpout/mc_addons_manager

Sur le coup je pensais c'était du wpf ton app en faite c'est du windows universal, bon après niveau fonctionnement ça ne diffère pas trop.

Plusieurs conseils travail avec des données brutes dans tes listes et non des usercontrol, c'est la partie Model dans MVVM, bon après ton application respecte pas trop le pattern MVVM mais tu es libre de faire comme tu veux.

Le mieux si tu travaille avec des itemscontrol, listview et autre c'est d'écrire directement le xaml (ou utiliser des resources) dans le datatemplate plutôt qu'y mettre un usercontrol, ça été galère pour faire fonctionner le binding :rire: et ca te fais ecrire du code redondant pour rien, à part si tu fais un traitement spécifique dans le code du usercontrol ...

Avec cette technologie on privilégie de travailler directement avec les données plutôt qu'un index pour récupérer l'item dans la liste, au final c'est plus simple; tu verras le fonctionnement du deletecommand.

Et ton erreur, et oui c'est pour ça que ta vue ne se mettait pas à jour quand tu supprimais un item de la liste c'est cette ligne dans ton usercontrol
Maps maps = new Maps(); maps.DeleteMap(index);

en faisant ça tu recréais un controls maps en mémoire et tu supprimais l'item sur celui-ci, mais c'est pas du tout le contrôle qui était affiché, il aurait fallu passé une référence du control maps à ton usercontrol.
Je ne sais pas si tu as compris ton erreur, si t'as besoin de plus d'explication n'hésite pas.

Pseudo supprimé
Niveau 6
08 juillet 2020 à 22:09:56

Merci beaucoup j'ai compris mon erreur ;)
Et désolé pour le message d'erreur étrange lors de la suppression que je viens de remarquer, on peut dire que ça commençais à m'énerver x)

Tout ça va m'être très utile, je vais voir le nouveau code en détail, pour comprendre mes autres erreurs, je te remercie encore :fete:

Bonne soirée !

boucif
Niveau 24
08 juillet 2020 à 23:33:31

Pas de problème bonne soirée
:ok:

1
Sujet : [UWP XAML C#] Impossible de retirer des éléments dans un StackPanel
   Retour haut de page
Consulter la version web de cette page