Mission 03 — CRUD
À l'issue de cette mission, vous saurez :
- modéliser une entité métier et son service de persistance
- implémenter un cycle complet Create / Read / Update / Delete
- afficher et filtrer une collection avec CollectionView et LINQ
Spec
- Modéliser la classe
Card: identifiant, recto, verso (+ ce que votre analyse juge utile). - Create : ajouter une carte via un formulaire ; recto et verso limités à 255 caractères et non vides (validation avec message d'erreur).
- Read : la liste des cartes s'affiche dans un
CollectionView(recto visible au minimum) ; prévoir l'affichage « liste vide ». - Update : éditer une carte existante en réutilisant la navigation avec paramètre de la mission 02.
- Delete : supprimer une carte avec confirmation.
- Persistance : les cartes survivent au redémarrage complet de l'application (JSON dans
FileSystem.AppDataDirectory). - Filtre : un champ de recherche réduit la liste aux cartes dont le recto ou le verso contient le texte saisi (insensible à la casse).
- (Optionnel — CDC 7.3) : plusieurs decks, recherche multi-termes ET/OU, autocomplétion.
Maquette
┌──────────────────────────┐ ┌──────────────────────────┐
│ Mes cartes [+] │ │ ← Éditer la carte │
│ ┌────────────────────┐ │ │ │
│ │ 🔍 Rechercher... │ │ │ Recto │
│ └────────────────────┘ │ │ ┌────────────────────┐ │
│ ┌────────────────────┐ │ │ │ Capitale de la CH ?│ │
│ │ Capitale de la CH ?│ │ │ └────────────────────┘ │
│ │ ✏️ 🗑️ │ │ │ Verso │
│ ├────────────────────┤ │ │ ┌────────────────────┐ │
│ │ 7 x 8 ? │ │ │ │ Berne │ │
│ │ ✏️ 🗑️ │ │ │ └────────────────────┘ │
│ └────────────────────┘ │ │ [ Sauvegarder ] │
│ │ │ [ Annuler ] │
└──────────────────────────┘ └──────────────────────────┘Théorie utile
- Structurer un projet : Models / Services / Pages
- Persister en JSON
- Afficher une collection avec CollectionView
- Formulaire et validation
- Filtrer avec LINQ
Indices
- Une
List<T>ne notifie pas la vue : après chaque modification, réassigner l'ItemsSource(ou utiliserObservableCollection). - Au retour de la page d'édition, rafraîchir la liste dans
OnAppearing. MaxLength="255"sur l'Entrybloque la saisie côté UI — mais validez aussi côté code.- Scroll du
CollectionViewcapricieux ? Voir le bug connu.
CommandParameter="{Binding .}"passe la carte complète au gestionnaire du bouton ✏️/🗑️.
Coup de pouce — service de persistance
csharp
public class CardDataService
{
private readonly string _filePath =
Path.Combine(FileSystem.AppDataDirectory, "cards.json");
public async Task<List<Card>> LoadAsync()
{
if (!File.Exists(_filePath)) return new List<Card>();
string json = await File.ReadAllTextAsync(_filePath);
return ...; // désérialiser (et gérer le cas null/erreur)
}
public async Task SaveAsync(List<Card> cards)
{
string json = ...; // sérialiser avec indentation
await File.WriteAllTextAsync(_filePath, json);
}
}Validation
- Suppression uniquement après confirmation
- Le filtre réduit la liste pendant la frappe et se réinitialise quand le champ est vidé
- Vous savez montrer le fichier JSON généré et expliquer son contenu
- Ajout d'une carte avec validation (vide et > 255 refusés avec message)
- Liste affichée, y compris l'état « aucune carte »
- Édition d'une carte existante fonctionnelle
- Les cartes sont toujours là après avoir tué et relancé l'app